feat: OpenAPI 3.0 spec with Swagger UI
- GET /openapi.yaml: raw OpenAPI spec - GET /openapi.json: JSON-formatted spec - GET /docs: Swagger UI for interactive API docs - 19 endpoints documented with schemas - Added pyyaml dependency
This commit is contained in:
2
TASKS.md
2
TASKS.md
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
### P3 - Low
|
### P3 - Low
|
||||||
- [ ] Add pagination to all list endpoints
|
- [ ] Add pagination to all list endpoints
|
||||||
- [ ] Add OpenAPI/Swagger spec
|
- [x] Add OpenAPI/Swagger spec
|
||||||
- [ ] Add request logging middleware
|
- [ ] Add request logging middleware
|
||||||
|
|
||||||
## Completed: v0.1.2 - OSINT Features
|
## Completed: v0.1.2 - OSINT Features
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ dependencies = [
|
|||||||
"flask-cors>=4.0",
|
"flask-cors>=4.0",
|
||||||
"gunicorn>=21.0",
|
"gunicorn>=21.0",
|
||||||
"python-dotenv>=1.0",
|
"python-dotenv>=1.0",
|
||||||
|
"pyyaml>=6.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"""ESP32-Web Flask Application."""
|
"""ESP32-Web Flask Application."""
|
||||||
import click
|
import click
|
||||||
from datetime import datetime, UTC
|
from datetime import datetime, UTC
|
||||||
from flask import Flask
|
from flask import Flask, Response, send_from_directory
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from .config import Config
|
from .config import Config
|
||||||
@@ -42,6 +42,45 @@ def create_app(config_class=Config):
|
|||||||
uptime_str = f'{minutes}m{seconds}s'
|
uptime_str = f'{minutes}m{seconds}s'
|
||||||
return {'status': 'ok', 'uptime': uptime_str, 'uptime_seconds': uptime_seconds}
|
return {'status': 'ok', 'uptime': uptime_str, 'uptime_seconds': uptime_seconds}
|
||||||
|
|
||||||
|
# OpenAPI spec endpoints
|
||||||
|
@app.route('/openapi.yaml')
|
||||||
|
def openapi_yaml():
|
||||||
|
"""Serve OpenAPI spec as YAML."""
|
||||||
|
spec_path = Path(__file__).parent / 'openapi.yaml'
|
||||||
|
return Response(spec_path.read_text(), mimetype='text/yaml')
|
||||||
|
|
||||||
|
@app.route('/openapi.json')
|
||||||
|
def openapi_json():
|
||||||
|
"""Serve OpenAPI spec as JSON."""
|
||||||
|
import json
|
||||||
|
import yaml
|
||||||
|
spec_path = Path(__file__).parent / 'openapi.yaml'
|
||||||
|
spec = yaml.safe_load(spec_path.read_text())
|
||||||
|
return spec
|
||||||
|
|
||||||
|
@app.route('/docs')
|
||||||
|
def swagger_ui():
|
||||||
|
"""Serve Swagger UI."""
|
||||||
|
return '''<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>ESP32-Web API</title>
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="swagger-ui"></div>
|
||||||
|
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
||||||
|
<script>
|
||||||
|
SwaggerUIBundle({
|
||||||
|
url: "/openapi.json",
|
||||||
|
dom_id: '#swagger-ui',
|
||||||
|
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
|
||||||
|
layout: "BaseLayout"
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>'''
|
||||||
|
|
||||||
# Start UDP collector in non-testing mode
|
# Start UDP collector in non-testing mode
|
||||||
if not app.config.get('TESTING'):
|
if not app.config.get('TESTING'):
|
||||||
from .collector import collector
|
from .collector import collector
|
||||||
|
|||||||
836
src/esp32_web/openapi.yaml
Normal file
836
src/esp32_web/openapi.yaml
Normal file
@@ -0,0 +1,836 @@
|
|||||||
|
openapi: 3.0.3
|
||||||
|
info:
|
||||||
|
title: ESP32-Web API
|
||||||
|
description: REST API for ESP32 sensor fleet management
|
||||||
|
version: 0.1.3
|
||||||
|
contact:
|
||||||
|
name: ESP32-Web
|
||||||
|
servers:
|
||||||
|
- url: /api/v1
|
||||||
|
description: API v1
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- name: sensors
|
||||||
|
description: Sensor management and fleet operations
|
||||||
|
- name: devices
|
||||||
|
description: Discovered BLE/WiFi devices
|
||||||
|
- name: alerts
|
||||||
|
description: Security alerts and anomalies
|
||||||
|
- name: events
|
||||||
|
description: Sensor events (motion, presence)
|
||||||
|
- name: probes
|
||||||
|
description: WiFi probe requests
|
||||||
|
- name: stats
|
||||||
|
description: Aggregate statistics
|
||||||
|
- name: export
|
||||||
|
description: Data export endpoints
|
||||||
|
|
||||||
|
paths:
|
||||||
|
/sensors:
|
||||||
|
get:
|
||||||
|
tags: [sensors]
|
||||||
|
summary: List all sensors
|
||||||
|
operationId: listSensors
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: List of sensors
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
sensors:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Sensor'
|
||||||
|
|
||||||
|
/sensors/heartbeat:
|
||||||
|
get:
|
||||||
|
tags: [sensors]
|
||||||
|
summary: Get heartbeat status for all sensors
|
||||||
|
operationId: getHeartbeatStatus
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Heartbeat summary
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/HeartbeatSummary'
|
||||||
|
post:
|
||||||
|
tags: [sensors]
|
||||||
|
summary: Refresh heartbeat status for all sensors
|
||||||
|
operationId: refreshHeartbeats
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Update result
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
example: updated
|
||||||
|
online:
|
||||||
|
type: integer
|
||||||
|
stale:
|
||||||
|
type: integer
|
||||||
|
offline:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
/sensors/{hostname}:
|
||||||
|
get:
|
||||||
|
tags: [sensors]
|
||||||
|
summary: Get sensor by hostname
|
||||||
|
operationId: getSensor
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/hostname'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Sensor details
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Sensor'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/sensors/{hostname}/command:
|
||||||
|
post:
|
||||||
|
tags: [sensors]
|
||||||
|
summary: Send UDP command to sensor
|
||||||
|
operationId: sendCommand
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/hostname'
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required: [command]
|
||||||
|
properties:
|
||||||
|
command:
|
||||||
|
type: string
|
||||||
|
example: STATUS
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Command sent
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
example: sent
|
||||||
|
command:
|
||||||
|
type: string
|
||||||
|
'403':
|
||||||
|
description: Command not allowed
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/sensors/{hostname}/config:
|
||||||
|
get:
|
||||||
|
tags: [sensors]
|
||||||
|
summary: Get sensor configuration
|
||||||
|
operationId: getSensorConfig
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/hostname'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Sensor configuration
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
config:
|
||||||
|
$ref: '#/components/schemas/SensorConfig'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
'504':
|
||||||
|
description: Sensor not responding
|
||||||
|
put:
|
||||||
|
tags: [sensors]
|
||||||
|
summary: Update sensor configuration
|
||||||
|
operationId: updateSensorConfig
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/hostname'
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
rate:
|
||||||
|
type: integer
|
||||||
|
description: CSI send rate (Hz)
|
||||||
|
power:
|
||||||
|
type: integer
|
||||||
|
description: TX power (dBm)
|
||||||
|
adaptive:
|
||||||
|
type: boolean
|
||||||
|
threshold:
|
||||||
|
type: number
|
||||||
|
ble:
|
||||||
|
type: boolean
|
||||||
|
csi_mode:
|
||||||
|
type: string
|
||||||
|
enum: [raw, amplitude, hybrid]
|
||||||
|
presence:
|
||||||
|
type: boolean
|
||||||
|
powersave:
|
||||||
|
type: boolean
|
||||||
|
chanscan:
|
||||||
|
type: boolean
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Update results
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
results:
|
||||||
|
type: object
|
||||||
|
errors:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/sensors/{hostname}/ota:
|
||||||
|
post:
|
||||||
|
tags: [sensors]
|
||||||
|
summary: Trigger OTA update
|
||||||
|
operationId: triggerOta
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/hostname'
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required: [url]
|
||||||
|
properties:
|
||||||
|
url:
|
||||||
|
type: string
|
||||||
|
format: uri
|
||||||
|
example: https://example.com/firmware.bin
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OTA triggered
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
example: ota_triggered
|
||||||
|
url:
|
||||||
|
type: string
|
||||||
|
'400':
|
||||||
|
description: Invalid URL
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/sensors/{hostname}/calibrate:
|
||||||
|
post:
|
||||||
|
tags: [sensors]
|
||||||
|
summary: Trigger baseline calibration
|
||||||
|
operationId: triggerCalibrate
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/hostname'
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
seconds:
|
||||||
|
type: integer
|
||||||
|
minimum: 3
|
||||||
|
maximum: 60
|
||||||
|
default: 10
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Calibration started
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
example: calibration_started
|
||||||
|
seconds:
|
||||||
|
type: integer
|
||||||
|
'400':
|
||||||
|
description: Invalid seconds value
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/sensors/{hostname}/metrics:
|
||||||
|
get:
|
||||||
|
tags: [sensors]
|
||||||
|
summary: Get sensor activity metrics
|
||||||
|
operationId: getSensorMetrics
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/hostname'
|
||||||
|
- name: hours
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
default: 24
|
||||||
|
minimum: 1
|
||||||
|
maximum: 168
|
||||||
|
description: Time range in hours (max 168)
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Sensor metrics
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/SensorMetrics'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/devices:
|
||||||
|
get:
|
||||||
|
tags: [devices]
|
||||||
|
summary: List discovered devices
|
||||||
|
operationId: listDevices
|
||||||
|
parameters:
|
||||||
|
- name: type
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [ble, wifi]
|
||||||
|
- $ref: '#/components/parameters/limit'
|
||||||
|
- $ref: '#/components/parameters/offset'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: List of devices
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
devices:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Device'
|
||||||
|
limit:
|
||||||
|
type: integer
|
||||||
|
offset:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
/devices/{mac}:
|
||||||
|
get:
|
||||||
|
tags: [devices]
|
||||||
|
summary: Get device by MAC address
|
||||||
|
operationId: getDevice
|
||||||
|
parameters:
|
||||||
|
- name: mac
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: aa:bb:cc:dd:ee:ff
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Device details with sightings
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/Device'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
sightings:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Sighting'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/alerts:
|
||||||
|
get:
|
||||||
|
tags: [alerts]
|
||||||
|
summary: List security alerts
|
||||||
|
operationId: listAlerts
|
||||||
|
parameters:
|
||||||
|
- name: type
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: sensor_id
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
- $ref: '#/components/parameters/hours'
|
||||||
|
- $ref: '#/components/parameters/limit'
|
||||||
|
- $ref: '#/components/parameters/offset'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: List of alerts
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
alerts:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Alert'
|
||||||
|
limit:
|
||||||
|
type: integer
|
||||||
|
offset:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
/events:
|
||||||
|
get:
|
||||||
|
tags: [events]
|
||||||
|
summary: List sensor events
|
||||||
|
operationId: listEvents
|
||||||
|
parameters:
|
||||||
|
- name: type
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: sensor_id
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
- $ref: '#/components/parameters/hours'
|
||||||
|
- $ref: '#/components/parameters/limit'
|
||||||
|
- $ref: '#/components/parameters/offset'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: List of events
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
events:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Event'
|
||||||
|
limit:
|
||||||
|
type: integer
|
||||||
|
offset:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
/probes:
|
||||||
|
get:
|
||||||
|
tags: [probes]
|
||||||
|
summary: List probe requests
|
||||||
|
operationId: listProbes
|
||||||
|
parameters:
|
||||||
|
- name: ssid
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- $ref: '#/components/parameters/hours'
|
||||||
|
- $ref: '#/components/parameters/limit'
|
||||||
|
- $ref: '#/components/parameters/offset'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: List of probe requests
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
probes:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Probe'
|
||||||
|
limit:
|
||||||
|
type: integer
|
||||||
|
offset:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
/probes/ssids:
|
||||||
|
get:
|
||||||
|
tags: [probes]
|
||||||
|
summary: List SSIDs with counts
|
||||||
|
operationId: listSsids
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/hours'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: SSID list with counts
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
ssids:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
ssid:
|
||||||
|
type: string
|
||||||
|
count:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
/stats:
|
||||||
|
get:
|
||||||
|
tags: [stats]
|
||||||
|
summary: Get aggregate statistics
|
||||||
|
operationId: getStats
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/hours'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Statistics
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Stats'
|
||||||
|
|
||||||
|
/export/devices.csv:
|
||||||
|
get:
|
||||||
|
tags: [export]
|
||||||
|
summary: Export devices as CSV
|
||||||
|
operationId: exportDevicesCsv
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: CSV file
|
||||||
|
content:
|
||||||
|
text/csv:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
/export/devices.json:
|
||||||
|
get:
|
||||||
|
tags: [export]
|
||||||
|
summary: Export devices as JSON
|
||||||
|
operationId: exportDevicesJson
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: JSON file
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Device'
|
||||||
|
|
||||||
|
/export/alerts.csv:
|
||||||
|
get:
|
||||||
|
tags: [export]
|
||||||
|
summary: Export alerts as CSV
|
||||||
|
operationId: exportAlertsCsv
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/hours'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: CSV file
|
||||||
|
content:
|
||||||
|
text/csv:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
/export/probes.csv:
|
||||||
|
get:
|
||||||
|
tags: [export]
|
||||||
|
summary: Export probes as CSV
|
||||||
|
operationId: exportProbesCsv
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/hours'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: CSV file
|
||||||
|
content:
|
||||||
|
text/csv:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
hostname:
|
||||||
|
name: hostname
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: muddy-storm
|
||||||
|
limit:
|
||||||
|
name: limit
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
default: 100
|
||||||
|
maximum: 1000
|
||||||
|
offset:
|
||||||
|
name: offset
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
default: 0
|
||||||
|
hours:
|
||||||
|
name: hours
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
default: 24
|
||||||
|
|
||||||
|
responses:
|
||||||
|
NotFound:
|
||||||
|
description: Resource not found
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
schemas:
|
||||||
|
Sensor:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
hostname:
|
||||||
|
type: string
|
||||||
|
ip:
|
||||||
|
type: string
|
||||||
|
last_seen:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
enum: [online, stale, offline, unknown]
|
||||||
|
|
||||||
|
SensorConfig:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
hostname:
|
||||||
|
type: string
|
||||||
|
ip:
|
||||||
|
type: string
|
||||||
|
version:
|
||||||
|
type: string
|
||||||
|
uptime:
|
||||||
|
type: string
|
||||||
|
rate:
|
||||||
|
type: integer
|
||||||
|
tx_power:
|
||||||
|
type: integer
|
||||||
|
adaptive:
|
||||||
|
type: boolean
|
||||||
|
ble:
|
||||||
|
type: boolean
|
||||||
|
presence:
|
||||||
|
type: boolean
|
||||||
|
powersave:
|
||||||
|
type: boolean
|
||||||
|
csi_mode:
|
||||||
|
type: string
|
||||||
|
channel:
|
||||||
|
type: integer
|
||||||
|
rssi:
|
||||||
|
type: number
|
||||||
|
heap:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
SensorMetrics:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
hostname:
|
||||||
|
type: string
|
||||||
|
hours:
|
||||||
|
type: integer
|
||||||
|
activity:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
sightings:
|
||||||
|
type: integer
|
||||||
|
alerts:
|
||||||
|
type: integer
|
||||||
|
events:
|
||||||
|
type: integer
|
||||||
|
recent_events:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Event'
|
||||||
|
|
||||||
|
HeartbeatSummary:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
total:
|
||||||
|
type: integer
|
||||||
|
online:
|
||||||
|
type: integer
|
||||||
|
stale:
|
||||||
|
type: integer
|
||||||
|
offline:
|
||||||
|
type: integer
|
||||||
|
sensors:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
hostname:
|
||||||
|
type: string
|
||||||
|
ip:
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
last_seen:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
seconds_ago:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
Device:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
mac:
|
||||||
|
type: string
|
||||||
|
device_type:
|
||||||
|
type: string
|
||||||
|
enum: [ble, wifi]
|
||||||
|
vendor:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
company_id:
|
||||||
|
type: integer
|
||||||
|
nullable: true
|
||||||
|
manufacturer:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
first_seen:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
last_seen:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
|
||||||
|
Sighting:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
device_id:
|
||||||
|
type: integer
|
||||||
|
sensor_id:
|
||||||
|
type: integer
|
||||||
|
rssi:
|
||||||
|
type: integer
|
||||||
|
timestamp:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
|
||||||
|
Alert:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
sensor_id:
|
||||||
|
type: integer
|
||||||
|
alert_type:
|
||||||
|
type: string
|
||||||
|
source_mac:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
target_mac:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
rssi:
|
||||||
|
type: integer
|
||||||
|
nullable: true
|
||||||
|
timestamp:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
|
||||||
|
Event:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
sensor_id:
|
||||||
|
type: integer
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
payload:
|
||||||
|
type: object
|
||||||
|
timestamp:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
|
||||||
|
Probe:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
sensor_id:
|
||||||
|
type: integer
|
||||||
|
device_id:
|
||||||
|
type: integer
|
||||||
|
ssid:
|
||||||
|
type: string
|
||||||
|
rssi:
|
||||||
|
type: integer
|
||||||
|
channel:
|
||||||
|
type: integer
|
||||||
|
timestamp:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
|
||||||
|
Stats:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
sensors:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
total:
|
||||||
|
type: integer
|
||||||
|
online:
|
||||||
|
type: integer
|
||||||
|
devices:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
total:
|
||||||
|
type: integer
|
||||||
|
ble:
|
||||||
|
type: integer
|
||||||
|
wifi:
|
||||||
|
type: integer
|
||||||
|
alerts:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
count:
|
||||||
|
type: integer
|
||||||
|
hours:
|
||||||
|
type: integer
|
||||||
|
events:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
count:
|
||||||
|
type: integer
|
||||||
|
hours:
|
||||||
|
type: integer
|
||||||
|
probes:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
count:
|
||||||
|
type: integer
|
||||||
|
hours:
|
||||||
|
type: integer
|
||||||
Reference in New Issue
Block a user