This commit is contained in:
2026-11-03 08:44:11 +01:00
parent cbf5f20c75
commit 0a9da4f9c5
13 changed files with 422 additions and 5 deletions
+53
View File
@@ -7,6 +7,20 @@ from config import sensors_database_uri
from models import Sensor, SensorReadout, db
def _parse_readout_ts(raw: str):
value = (raw or "").strip()
if not value:
return None
if value.endswith("Z"):
value = value[:-1]
try:
parsed = datetime.fromisoformat(value)
except ValueError:
return None
if parsed.tzinfo is not None:
parsed = parsed.astimezone(timezone.utc).replace(tzinfo=None)
return parsed
def create_app():
app = Flask(__name__)
@@ -78,6 +92,45 @@ def create_app():
}
), 201
@app.route("/api/sensors/<int:sensor_id>/readouts/range")
def api_sensor_readouts_range(sensor_id):
sensor = db.session.get(Sensor, sensor_id)
if not sensor:
return jsonify({"error": "sensor not found"}), 404
from_raw = request.args.get("from")
to_raw = request.args.get("to")
from_ts = _parse_readout_ts(from_raw) if from_raw else None
to_ts = _parse_readout_ts(to_raw) if to_raw else None
if from_ts is None or to_ts is None or to_ts < from_ts:
return jsonify({"error": "from and to are required and valid"}), 400
rows = (
db.session.query(
SensorReadout.id,
SensorReadout.sensor_id,
SensorReadout.type,
SensorReadout.value,
SensorReadout.timestamp,
)
.filter(SensorReadout.sensor_id == sensor_id)
.filter(SensorReadout.timestamp >= from_ts, SensorReadout.timestamp < to_ts)
.order_by(SensorReadout.timestamp)
.all()
)
return jsonify(
[
{
"id": row[0],
"sensor_id": row[1],
"type": row[2],
"value": row[3],
"timestamp": row[4].isoformat() + "Z",
}
for row in rows
]
)
# --- API: dashboard reads (public on the local machine) ---
@app.route("/api/sensors/<int:sensor_id>/types")