|
|
@@ -1,743 +0,0 @@
|
|
|
-openapi: 3.1.0
|
|
|
-info:
|
|
|
- title: Getränkeautomat Monitor API
|
|
|
- version: 1.0.0
|
|
|
- summary: HTTP API for ingesting sensor readings and retrieving vending machine status.
|
|
|
- description: |
|
|
|
- Handwritten OpenAPI specification for the Getränkeautomat Monitor application.
|
|
|
-
|
|
|
- The API currently exposes two endpoints:
|
|
|
- - `POST /api/v1/readings.php` for ingesting one sensor measurement
|
|
|
- - `GET /api/v1/status.php` for retrieving the aggregated application state
|
|
|
-
|
|
|
- The readings endpoint uses Bearer token authentication. The status endpoint is
|
|
|
- intentionally public so the dashboard can poll it without a login.
|
|
|
-servers:
|
|
|
- - url: ./
|
|
|
- description: Same-origin deployment
|
|
|
-tags:
|
|
|
- - name: Readings
|
|
|
- description: Receive one sensor reading and update the persisted slot state.
|
|
|
- - name: Status
|
|
|
- description: Retrieve the current aggregated machine, slot, and alert status.
|
|
|
-paths:
|
|
|
- /api/v1/readings.php:
|
|
|
- post:
|
|
|
- tags:
|
|
|
- - Readings
|
|
|
- summary: Submit one reading
|
|
|
- description: |
|
|
|
- Accepts exactly one sensor measurement for one configured machine slot.
|
|
|
-
|
|
|
- Processing behavior:
|
|
|
- - Requires a Bearer token in the `Authorization` header
|
|
|
- - Accepts JSON request bodies
|
|
|
- - Updates `data/state.json` on success
|
|
|
- - Treats `distance_mm: -1` as a client-side measurement error, keeps
|
|
|
- the last good slot value, and stores input-error metadata for the UI
|
|
|
- - Triggers alerts only when the slot state changes from `ok` to `critical`
|
|
|
- or from `critical` to `ok`
|
|
|
- operationId: submitReading
|
|
|
- security:
|
|
|
- - bearerAuth: []
|
|
|
- requestBody:
|
|
|
- required: true
|
|
|
- content:
|
|
|
- application/json:
|
|
|
- schema:
|
|
|
- $ref: '#/components/schemas/ReadingRequest'
|
|
|
- examples:
|
|
|
- lobbySlot:
|
|
|
- summary: Reading for the A1 slot in the lobby machine
|
|
|
- value:
|
|
|
- machine_id: automat-lobby
|
|
|
- sensor_id: fach-a1
|
|
|
- distance_mm: 184
|
|
|
- measured_at: '2026-04-15T19:20:00Z'
|
|
|
- clientError:
|
|
|
- summary: Client-side measurement error for the A1 slot
|
|
|
- value:
|
|
|
- machine_id: automat-lobby
|
|
|
- sensor_id: fach-a1
|
|
|
- distance_mm: -1
|
|
|
- measured_at: '2026-04-15T19:22:09Z'
|
|
|
- responses:
|
|
|
- '200':
|
|
|
- description: Reading processed successfully.
|
|
|
- content:
|
|
|
- application/json:
|
|
|
- schema:
|
|
|
- $ref: '#/components/schemas/ReadingSuccessResponse'
|
|
|
- examples:
|
|
|
- ok:
|
|
|
- value:
|
|
|
- ok: true
|
|
|
- machine_id: automat-lobby
|
|
|
- sensor_id: fach-a1
|
|
|
- slot_label: A1
|
|
|
- units_estimated: 4
|
|
|
- fill_percent: 63
|
|
|
- state: ok
|
|
|
- clientError:
|
|
|
- value:
|
|
|
- ok: true
|
|
|
- machine_id: automat-lobby
|
|
|
- sensor_id: fach-a1
|
|
|
- slot_label: A1
|
|
|
- units_estimated: 4
|
|
|
- fill_percent: 63
|
|
|
- state: ok
|
|
|
- input_error:
|
|
|
- received_at: '2026-04-15T19:22:10+00:00'
|
|
|
- measured_at: '2026-04-15T19:22:09+00:00'
|
|
|
- reported_value: -1
|
|
|
- message: Client meldete einen Messfehler.
|
|
|
- last_good:
|
|
|
- distance_mm: 184
|
|
|
- fill_percent: 63
|
|
|
- units_estimated: 4
|
|
|
- max_units: 7
|
|
|
- state: ok
|
|
|
- measured_at: '2026-04-15T19:20:00+00:00'
|
|
|
- '400':
|
|
|
- description: Invalid JSON body or malformed request payload.
|
|
|
- content:
|
|
|
- application/json:
|
|
|
- schema:
|
|
|
- $ref: '#/components/schemas/ErrorResponse'
|
|
|
- examples:
|
|
|
- invalidJson:
|
|
|
- value:
|
|
|
- ok: false
|
|
|
- error: Ungültiger JSON-Body.
|
|
|
- '401':
|
|
|
- description: Missing or invalid Bearer token.
|
|
|
- content:
|
|
|
- application/json:
|
|
|
- schema:
|
|
|
- $ref: '#/components/schemas/ErrorResponse'
|
|
|
- examples:
|
|
|
- unauthorized:
|
|
|
- value:
|
|
|
- ok: false
|
|
|
- error: Nicht autorisiert.
|
|
|
- '404':
|
|
|
- description: The referenced machine or sensor is not configured.
|
|
|
- content:
|
|
|
- application/json:
|
|
|
- schema:
|
|
|
- $ref: '#/components/schemas/ErrorResponse'
|
|
|
- examples:
|
|
|
- unknownMachineOrSensor:
|
|
|
- value:
|
|
|
- ok: false
|
|
|
- error: Unbekannter Automat oder Sensor.
|
|
|
- '405':
|
|
|
- description: Only POST is supported for this endpoint.
|
|
|
- content:
|
|
|
- application/json:
|
|
|
- schema:
|
|
|
- $ref: '#/components/schemas/ErrorResponse'
|
|
|
- examples:
|
|
|
- wrongMethod:
|
|
|
- value:
|
|
|
- ok: false
|
|
|
- error: Nur POST ist erlaubt.
|
|
|
- '422':
|
|
|
- description: Semantic validation failed.
|
|
|
- content:
|
|
|
- application/json:
|
|
|
- schema:
|
|
|
- $ref: '#/components/schemas/ErrorResponse'
|
|
|
- examples:
|
|
|
- missingIdentifiers:
|
|
|
- value:
|
|
|
- ok: false
|
|
|
- error: machine_id und sensor_id sind erforderlich.
|
|
|
- nonNumericDistance:
|
|
|
- value:
|
|
|
- ok: false
|
|
|
- error: distance_mm muss numerisch sein.
|
|
|
- invalidTimestamp:
|
|
|
- value:
|
|
|
- ok: false
|
|
|
- error: measured_at ist kein gültiger ISO-Zeitstempel.
|
|
|
- '500':
|
|
|
- description: Unexpected internal server error.
|
|
|
- content:
|
|
|
- application/json:
|
|
|
- schema:
|
|
|
- $ref: '#/components/schemas/ErrorResponse'
|
|
|
- examples:
|
|
|
- internalError:
|
|
|
- value:
|
|
|
- ok: false
|
|
|
- error: Interner Fehler.
|
|
|
- options:
|
|
|
- tags:
|
|
|
- - Readings
|
|
|
- summary: CORS preflight for readings
|
|
|
- description: |
|
|
|
- Preflight handler for browser-based clients. The endpoint responds with
|
|
|
- `204 No Content` and emits `Access-Control-Allow-Methods` and
|
|
|
- `Access-Control-Allow-Headers`.
|
|
|
- operationId: readingsPreflight
|
|
|
- responses:
|
|
|
- '204':
|
|
|
- description: Preflight accepted without a response body.
|
|
|
- headers:
|
|
|
- Access-Control-Allow-Methods:
|
|
|
- description: Allowed methods for this endpoint.
|
|
|
- schema:
|
|
|
- type: string
|
|
|
- example: POST, OPTIONS
|
|
|
- Access-Control-Allow-Headers:
|
|
|
- description: Allowed request headers for this endpoint.
|
|
|
- schema:
|
|
|
- type: string
|
|
|
- example: Authorization, Content-Type
|
|
|
- /api/v1/status.php:
|
|
|
- get:
|
|
|
- tags:
|
|
|
- - Status
|
|
|
- summary: Retrieve the current application status
|
|
|
- description: |
|
|
|
- Returns the aggregated state for the dashboard and admin panel.
|
|
|
-
|
|
|
- The response contains:
|
|
|
- - app metadata
|
|
|
- - machine and slot status
|
|
|
- - a summary section
|
|
|
- - the most recent alert log entries
|
|
|
- operationId: getStatus
|
|
|
- responses:
|
|
|
- '200':
|
|
|
- description: Aggregated status generated successfully.
|
|
|
- content:
|
|
|
- application/json:
|
|
|
- schema:
|
|
|
- $ref: '#/components/schemas/StatusResponse'
|
|
|
- examples:
|
|
|
- dashboard:
|
|
|
- value:
|
|
|
- ok: true
|
|
|
- generated_at: '2026-04-15T20:10:00+00:00'
|
|
|
- app:
|
|
|
- name: Getränkeautomat Monitor
|
|
|
- dashboard_refresh_seconds: 15
|
|
|
- summary:
|
|
|
- machine_count: 2
|
|
|
- slot_count: 3
|
|
|
- critical_count: 1
|
|
|
- machines:
|
|
|
- - id: automat-lobby
|
|
|
- name: Lobby Automat
|
|
|
- location: Erdgeschoss
|
|
|
- slots:
|
|
|
- - machine_id: automat-lobby
|
|
|
- machine_name: Lobby Automat
|
|
|
- sensor_id: fach-a1
|
|
|
- slot_label: A1
|
|
|
- product_name: Cola 0,5l
|
|
|
- fill_percent: 63
|
|
|
- units_estimated: 4
|
|
|
- max_units: 7
|
|
|
- distance_mm: 184
|
|
|
- state: ok
|
|
|
- measured_at: '2026-04-15T19:20:00+00:00'
|
|
|
- updated_at: '2026-04-15T19:20:02+00:00'
|
|
|
- alert_below_units: 2
|
|
|
- alerts:
|
|
|
- - id: alert_680004979d8512.07480974
|
|
|
- created_at: '2026-04-15T19:20:02+00:00'
|
|
|
- payload:
|
|
|
- event: critical
|
|
|
- machine_id: automat-lobby
|
|
|
- machine_name: Lobby Automat
|
|
|
- sensor_id: fach-a1
|
|
|
- slot_label: A1
|
|
|
- product_name: Cola 0,5l
|
|
|
- distance_mm: 320
|
|
|
- units_estimated: 1
|
|
|
- max_units: 7
|
|
|
- fill_percent: 14
|
|
|
- state: critical
|
|
|
- previous_state: ok
|
|
|
- measured_at: '2026-04-15T19:19:59+00:00'
|
|
|
- deliveries:
|
|
|
- webhooks:
|
|
|
- - label: lager-webhook
|
|
|
- success: false
|
|
|
- message: Webhook nicht gefunden oder deaktiviert.
|
|
|
- emails:
|
|
|
- - label: lager-team
|
|
|
- success: true
|
|
|
- message: Email versendet.
|
|
|
- '405':
|
|
|
- description: Only GET is supported for this endpoint.
|
|
|
- content:
|
|
|
- application/json:
|
|
|
- schema:
|
|
|
- $ref: '#/components/schemas/ErrorResponse'
|
|
|
- examples:
|
|
|
- wrongMethod:
|
|
|
- value:
|
|
|
- ok: false
|
|
|
- error: Nur GET ist erlaubt.
|
|
|
-components:
|
|
|
- securitySchemes:
|
|
|
- bearerAuth:
|
|
|
- type: http
|
|
|
- scheme: bearer
|
|
|
- bearerFormat: opaque token
|
|
|
- description: Bearer token stored in config.json under api.bearer_token.
|
|
|
- schemas:
|
|
|
- ReadingRequest:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - machine_id
|
|
|
- - sensor_id
|
|
|
- - distance_mm
|
|
|
- properties:
|
|
|
- machine_id:
|
|
|
- type: string
|
|
|
- description: Configured machine identifier from config.json.
|
|
|
- minLength: 1
|
|
|
- example: automat-lobby
|
|
|
- sensor_id:
|
|
|
- type: string
|
|
|
- description: Slot or sensor identifier within the machine.
|
|
|
- minLength: 1
|
|
|
- example: fach-a1
|
|
|
- distance_mm:
|
|
|
- type: number
|
|
|
- description: Measured distance in millimeters. The sentinel value `-1` reports a client-side measurement error and does not replace the last good slot value.
|
|
|
- example: 184
|
|
|
- measured_at:
|
|
|
- type:
|
|
|
- - string
|
|
|
- - 'null'
|
|
|
- description: |
|
|
|
- Optional measurement timestamp. When omitted or empty, the server uses
|
|
|
- the current time. Values are parsed with PHP `strtotime()` and returned
|
|
|
- as an ISO-8601 timestamp.
|
|
|
- format: date-time
|
|
|
- example: '2026-04-15T19:20:00Z'
|
|
|
- ReadingSuccessResponse:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - ok
|
|
|
- - machine_id
|
|
|
- - sensor_id
|
|
|
- - slot_label
|
|
|
- - units_estimated
|
|
|
- - fill_percent
|
|
|
- - state
|
|
|
- properties:
|
|
|
- ok:
|
|
|
- type: boolean
|
|
|
- const: true
|
|
|
- machine_id:
|
|
|
- type: string
|
|
|
- example: automat-lobby
|
|
|
- sensor_id:
|
|
|
- type: string
|
|
|
- example: fach-a1
|
|
|
- slot_label:
|
|
|
- type: string
|
|
|
- example: A1
|
|
|
- units_estimated:
|
|
|
- type:
|
|
|
- - integer
|
|
|
- - 'null'
|
|
|
- example: 4
|
|
|
- fill_percent:
|
|
|
- type:
|
|
|
- - integer
|
|
|
- - 'null'
|
|
|
- example: 63
|
|
|
- state:
|
|
|
- $ref: '#/components/schemas/SlotState'
|
|
|
- input_error:
|
|
|
- oneOf:
|
|
|
- - $ref: '#/components/schemas/InputError'
|
|
|
- - type: 'null'
|
|
|
- ErrorResponse:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - ok
|
|
|
- - error
|
|
|
- properties:
|
|
|
- ok:
|
|
|
- type: boolean
|
|
|
- const: false
|
|
|
- error:
|
|
|
- type: string
|
|
|
- example: Nicht autorisiert.
|
|
|
- StatusResponse:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - ok
|
|
|
- - generated_at
|
|
|
- - app
|
|
|
- - summary
|
|
|
- - machines
|
|
|
- - alerts
|
|
|
- properties:
|
|
|
- ok:
|
|
|
- type: boolean
|
|
|
- const: true
|
|
|
- generated_at:
|
|
|
- type: string
|
|
|
- format: date-time
|
|
|
- description: Timestamp when the response was generated.
|
|
|
- app:
|
|
|
- $ref: '#/components/schemas/AppStatus'
|
|
|
- summary:
|
|
|
- $ref: '#/components/schemas/StatusSummary'
|
|
|
- machines:
|
|
|
- type: array
|
|
|
- items:
|
|
|
- $ref: '#/components/schemas/MachineStatus'
|
|
|
- alerts:
|
|
|
- type: array
|
|
|
- items:
|
|
|
- $ref: '#/components/schemas/AlertEvent'
|
|
|
- AppStatus:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - name
|
|
|
- - dashboard_refresh_seconds
|
|
|
- properties:
|
|
|
- name:
|
|
|
- type: string
|
|
|
- example: Getränkeautomat Monitor
|
|
|
- dashboard_refresh_seconds:
|
|
|
- type: integer
|
|
|
- minimum: 1
|
|
|
- example: 15
|
|
|
- StatusSummary:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - machine_count
|
|
|
- - slot_count
|
|
|
- - critical_count
|
|
|
- properties:
|
|
|
- machine_count:
|
|
|
- type: integer
|
|
|
- minimum: 0
|
|
|
- example: 2
|
|
|
- slot_count:
|
|
|
- type: integer
|
|
|
- minimum: 0
|
|
|
- example: 3
|
|
|
- critical_count:
|
|
|
- type: integer
|
|
|
- minimum: 0
|
|
|
- example: 1
|
|
|
- MachineStatus:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - id
|
|
|
- - name
|
|
|
- - location
|
|
|
- - slots
|
|
|
- properties:
|
|
|
- id:
|
|
|
- type: string
|
|
|
- example: automat-lobby
|
|
|
- name:
|
|
|
- type: string
|
|
|
- example: Lobby Automat
|
|
|
- location:
|
|
|
- type: string
|
|
|
- example: Erdgeschoss
|
|
|
- slots:
|
|
|
- type: array
|
|
|
- items:
|
|
|
- $ref: '#/components/schemas/SlotStatus'
|
|
|
- SlotStatus:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - machine_id
|
|
|
- - machine_name
|
|
|
- - sensor_id
|
|
|
- - slot_label
|
|
|
- - product_name
|
|
|
- - fill_percent
|
|
|
- - units_estimated
|
|
|
- - max_units
|
|
|
- - distance_mm
|
|
|
- - state
|
|
|
- - measured_at
|
|
|
- - updated_at
|
|
|
- - alert_below_units
|
|
|
- properties:
|
|
|
- machine_id:
|
|
|
- type: string
|
|
|
- example: automat-lobby
|
|
|
- machine_name:
|
|
|
- type: string
|
|
|
- example: Lobby Automat
|
|
|
- sensor_id:
|
|
|
- type: string
|
|
|
- example: fach-a1
|
|
|
- slot_label:
|
|
|
- type: string
|
|
|
- example: A1
|
|
|
- product_name:
|
|
|
- type: string
|
|
|
- example: Cola 0,5l
|
|
|
- fill_percent:
|
|
|
- type:
|
|
|
- - integer
|
|
|
- - 'null'
|
|
|
- minimum: 0
|
|
|
- maximum: 100
|
|
|
- description: Null until a first reading has been received.
|
|
|
- example: 63
|
|
|
- units_estimated:
|
|
|
- type:
|
|
|
- - integer
|
|
|
- - 'null'
|
|
|
- minimum: 0
|
|
|
- description: Null until a first reading has been received.
|
|
|
- example: 4
|
|
|
- max_units:
|
|
|
- type: integer
|
|
|
- minimum: 0
|
|
|
- example: 7
|
|
|
- distance_mm:
|
|
|
- type:
|
|
|
- - number
|
|
|
- - 'null'
|
|
|
- description: Last measured distance in millimeters.
|
|
|
- example: 184
|
|
|
- state:
|
|
|
- $ref: '#/components/schemas/SlotState'
|
|
|
- measured_at:
|
|
|
- type:
|
|
|
- - string
|
|
|
- - 'null'
|
|
|
- format: date-time
|
|
|
- example: '2026-04-15T19:20:00+00:00'
|
|
|
- updated_at:
|
|
|
- type:
|
|
|
- - string
|
|
|
- - 'null'
|
|
|
- format: date-time
|
|
|
- example: '2026-04-15T19:20:02+00:00'
|
|
|
- alert_below_units:
|
|
|
- type: integer
|
|
|
- minimum: 0
|
|
|
- example: 2
|
|
|
- input_error:
|
|
|
- oneOf:
|
|
|
- - $ref: '#/components/schemas/InputError'
|
|
|
- - type: 'null'
|
|
|
- description: Present when the most recent submitted value for this slot was `-1`.
|
|
|
- InputError:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - received_at
|
|
|
- - measured_at
|
|
|
- - reported_value
|
|
|
- - message
|
|
|
- - last_good
|
|
|
- properties:
|
|
|
- received_at:
|
|
|
- type: string
|
|
|
- format: date-time
|
|
|
- description: Server time when the `-1` value was received.
|
|
|
- example: '2026-04-15T19:22:10+00:00'
|
|
|
- measured_at:
|
|
|
- type: string
|
|
|
- format: date-time
|
|
|
- description: Timestamp supplied by the client for the failed reading, or the server time when omitted.
|
|
|
- example: '2026-04-15T19:22:09+00:00'
|
|
|
- reported_value:
|
|
|
- type: integer
|
|
|
- const: -1
|
|
|
- message:
|
|
|
- type: string
|
|
|
- example: Client meldete einen Messfehler.
|
|
|
- last_good:
|
|
|
- oneOf:
|
|
|
- - $ref: '#/components/schemas/LastGoodReading'
|
|
|
- - type: 'null'
|
|
|
- description: Last successfully calculated slot data, if any exists.
|
|
|
- LastGoodReading:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - distance_mm
|
|
|
- - fill_percent
|
|
|
- - units_estimated
|
|
|
- - max_units
|
|
|
- - state
|
|
|
- - measured_at
|
|
|
- properties:
|
|
|
- distance_mm:
|
|
|
- type: number
|
|
|
- example: 184
|
|
|
- fill_percent:
|
|
|
- type: integer
|
|
|
- minimum: 0
|
|
|
- maximum: 100
|
|
|
- example: 63
|
|
|
- units_estimated:
|
|
|
- type: integer
|
|
|
- minimum: 0
|
|
|
- example: 4
|
|
|
- max_units:
|
|
|
- type: integer
|
|
|
- minimum: 0
|
|
|
- example: 7
|
|
|
- state:
|
|
|
- $ref: '#/components/schemas/SlotState'
|
|
|
- measured_at:
|
|
|
- type: string
|
|
|
- format: date-time
|
|
|
- example: '2026-04-15T19:20:00+00:00'
|
|
|
- SlotState:
|
|
|
- type: string
|
|
|
- enum:
|
|
|
- - ok
|
|
|
- - critical
|
|
|
- - unknown
|
|
|
- example: ok
|
|
|
- AlertEvent:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - id
|
|
|
- - created_at
|
|
|
- - payload
|
|
|
- - deliveries
|
|
|
- properties:
|
|
|
- id:
|
|
|
- type: string
|
|
|
- description: Unique alert log entry ID generated with PHP uniqid().
|
|
|
- example: alert_680004979d8512.07480974
|
|
|
- created_at:
|
|
|
- type: string
|
|
|
- format: date-time
|
|
|
- example: '2026-04-15T19:20:02+00:00'
|
|
|
- payload:
|
|
|
- $ref: '#/components/schemas/AlertPayload'
|
|
|
- deliveries:
|
|
|
- $ref: '#/components/schemas/AlertDeliveries'
|
|
|
- AlertPayload:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - event
|
|
|
- - machine_id
|
|
|
- - machine_name
|
|
|
- - sensor_id
|
|
|
- - slot_label
|
|
|
- - product_name
|
|
|
- - distance_mm
|
|
|
- - units_estimated
|
|
|
- - max_units
|
|
|
- - fill_percent
|
|
|
- - state
|
|
|
- - previous_state
|
|
|
- - measured_at
|
|
|
- properties:
|
|
|
- event:
|
|
|
- type: string
|
|
|
- enum:
|
|
|
- - critical
|
|
|
- - recovered
|
|
|
- example: critical
|
|
|
- machine_id:
|
|
|
- type: string
|
|
|
- example: automat-lobby
|
|
|
- machine_name:
|
|
|
- type: string
|
|
|
- example: Lobby Automat
|
|
|
- sensor_id:
|
|
|
- type: string
|
|
|
- example: fach-a1
|
|
|
- slot_label:
|
|
|
- type: string
|
|
|
- example: A1
|
|
|
- product_name:
|
|
|
- type: string
|
|
|
- example: Cola 0,5l
|
|
|
- distance_mm:
|
|
|
- type:
|
|
|
- - number
|
|
|
- - 'null'
|
|
|
- example: 320
|
|
|
- units_estimated:
|
|
|
- type:
|
|
|
- - integer
|
|
|
- - 'null'
|
|
|
- example: 1
|
|
|
- max_units:
|
|
|
- type:
|
|
|
- - integer
|
|
|
- - 'null'
|
|
|
- example: 7
|
|
|
- fill_percent:
|
|
|
- type:
|
|
|
- - integer
|
|
|
- - 'null'
|
|
|
- example: 14
|
|
|
- state:
|
|
|
- $ref: '#/components/schemas/SlotState'
|
|
|
- previous_state:
|
|
|
- type:
|
|
|
- - string
|
|
|
- - 'null'
|
|
|
- description: Previous slot state before the transition.
|
|
|
- example: ok
|
|
|
- measured_at:
|
|
|
- type:
|
|
|
- - string
|
|
|
- - 'null'
|
|
|
- format: date-time
|
|
|
- example: '2026-04-15T19:19:59+00:00'
|
|
|
- AlertDeliveries:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - webhooks
|
|
|
- - emails
|
|
|
- properties:
|
|
|
- webhooks:
|
|
|
- type: array
|
|
|
- items:
|
|
|
- $ref: '#/components/schemas/DeliveryResult'
|
|
|
- emails:
|
|
|
- type: array
|
|
|
- items:
|
|
|
- $ref: '#/components/schemas/DeliveryResult'
|
|
|
- DeliveryResult:
|
|
|
- type: object
|
|
|
- additionalProperties: false
|
|
|
- required:
|
|
|
- - id
|
|
|
- - success
|
|
|
- - message
|
|
|
- properties:
|
|
|
- id:
|
|
|
- type: string
|
|
|
- example: lager-team
|
|
|
- success:
|
|
|
- type: boolean
|
|
|
- example: true
|
|
|
- message:
|
|
|
- type: string
|
|
|
- example: Email versendet.
|