Commit 07514b02 authored by Gezer's avatar Gezer
Browse files

Refactor sensor availability endpoint and schemas; update response to include...

Refactor sensor availability endpoint and schemas; update response to include detailed sensor availability data
parent 1bb98d22
...@@ -7,6 +7,7 @@ from dotenv import load_dotenv ...@@ -7,6 +7,7 @@ from dotenv import load_dotenv
import os import os
from app.schemas.sensor import ( from app.schemas.sensor import (
AllSensorsAvailabilityResponseDetail,
RoomDataRangeResponse, RoomDataRangeResponse,
GetRoomsResponse, GetRoomsResponse,
RoomDataCSVResponse, RoomDataCSVResponse,
...@@ -14,6 +15,7 @@ from app.schemas.sensor import ( ...@@ -14,6 +15,7 @@ from app.schemas.sensor import (
GetRoomsFromBuildingResponse, GetRoomsFromBuildingResponse,
GetBauResponse, GetBauResponse,
RoomAvailabilityResponse, RoomAvailabilityResponse,
SensorAvailability,
SensorAvailabilityResponse, SensorAvailabilityResponse,
AllRoomsAvailabilityResponse, AllRoomsAvailabilityResponse,
AllSensorsAvailabilityResponse, AllSensorsAvailabilityResponse,
...@@ -196,7 +198,6 @@ def sensor_availability(request, mac: str, start: str = "-30d", stop: str = "now ...@@ -196,7 +198,6 @@ def sensor_availability(request, mac: str, start: str = "-30d", stop: str = "now
return {"sensor_mac": mac, "available": availability} return {"sensor_mac": mac, "available": availability}
@sensor_router.get("/all_rooms_availability", response=AllRoomsAvailabilityResponse) @sensor_router.get("/all_rooms_availability", response=AllRoomsAvailabilityResponse)
def all_rooms_availability(request, start: str = "-30d", stop: str = "now()"): def all_rooms_availability(request, start: str = "-30d", stop: str = "now()"):
client = InfluxDBHelper( client = InfluxDBHelper(
...@@ -211,7 +212,7 @@ def all_rooms_availability(request, start: str = "-30d", stop: str = "now()"): ...@@ -211,7 +212,7 @@ def all_rooms_availability(request, start: str = "-30d", stop: str = "now()"):
return {"available_rooms": rooms_available} return {"available_rooms": rooms_available}
@sensor_router.get("/all_sensors_availability", response=AllSensorsAvailabilityResponse) @sensor_router.get("/all_room_sensors_availability", response=AllSensorsAvailabilityResponseDetail)
def all_sensors_availability(request, start: str = "-30d", stop: str = "now()"): def all_sensors_availability(request, start: str = "-30d", stop: str = "now()"):
client = InfluxDBHelper( client = InfluxDBHelper(
url=os.getenv("INFLUXDB_URL"), url=os.getenv("INFLUXDB_URL"),
...@@ -220,6 +221,13 @@ def all_sensors_availability(request, start: str = "-30d", stop: str = "now()"): ...@@ -220,6 +221,13 @@ def all_sensors_availability(request, start: str = "-30d", stop: str = "now()"):
bucket=os.getenv("INFLUXDB_BUCKET"), bucket=os.getenv("INFLUXDB_BUCKET"),
) )
sensors_available = client.sensors_with_available_data(start, stop) sensor_data = client.devices_with_availability_status(start, stop)
# Konvertiere dicts zu echten Pydantic-Schema-Objekten
sensors = [SensorAvailability(**item) for item in sensor_data]
print(f"sensors: {sensors}")
return {"sensors": sensors}
return {"available_sensors": sensors_available}
...@@ -60,6 +60,14 @@ class AllRoomsAvailabilityResponse(Schema): ...@@ -60,6 +60,14 @@ class AllRoomsAvailabilityResponse(Schema):
class AllSensorsAvailabilityResponse(Schema): class AllSensorsAvailabilityResponse(Schema):
available_sensors: List[str] available_sensors: List[str]
class SensorAvailability(Schema):
mac_address: str
room: str
availabil: str # "true" oder "false"
class AllSensorsAvailabilityResponseDetail(Schema):
sensors: List[SensorAvailability]
class Error(Schema): class Error(Schema):
......
...@@ -4,6 +4,12 @@ from influxdb_client.client.write_api import WriteOptions ...@@ -4,6 +4,12 @@ from influxdb_client.client.write_api import WriteOptions
class InfluxDBHelper: class InfluxDBHelper:
MEASUREMENT_NAME = "sensor_data"
TAG_ROOM = "room"
TAG_MAC = "mac"
FIELD_CO2 = "co2"
FIELD_TEMP = "temperature"
FIELD_HUMIDITY = "humidity"
def __init__(self, url: str, token: str, org: str, bucket: str): def __init__(self, url: str, token: str, org: str, bucket: str):
self.client = InfluxDBClient(url=url, token=token, org=org) self.client = InfluxDBClient(url=url, token=token, org=org)
self.bucket = bucket self.bucket = bucket
...@@ -159,3 +165,60 @@ class InfluxDBHelper: ...@@ -159,3 +165,60 @@ class InfluxDBHelper:
if self.has_sensor_sent_data(mac, start, stop): if self.has_sensor_sent_data(mac, start, stop):
available_sensors.append(mac) available_sensors.append(mac)
return available_sensors return available_sensors
def derive_mac_to_room_mapping(self) -> dict:
query = f'''
from(bucket: "{self.bucket}")
|> range(start: -90d)
|> filter(fn: (r) => r["_measurement"] == "{self.MEASUREMENT_NAME}")
|> filter(fn: (r) => exists r["{self.TAG_MAC}"] and exists r["{self.TAG_ROOM}"])
|> keep(columns: ["{self.TAG_MAC}", "{self.TAG_ROOM}"])
|> drop(columns: ["_start", "_stop", "_time", "_field", "_value"])
|> distinct()
'''
result = self.query_api.query(org=self.org, query=query)
mapping = {}
for table in result:
for record in table.records:
mac = record.values.get(self.TAG_MAC)
room = record.values.get(self.TAG_ROOM)
if mac and room:
mapping[mac] = room
print("Mapping record:", record.values)
return mapping
def devices_with_availability_status(self, start: str = "-30d", stop: str = "now()") -> list:
# 1. Alle MACs holen
macs_query = f'''
import "influxdata/influxdb/schema"
schema.tagValues(
bucket: "{self.bucket}",
tag: "{self.TAG_MAC}"
)
'''
macs_result = self.query_api.query(org=self.org, query=macs_query)
macs = [record.get_value() for table in macs_result for record in table.records]
# 2. Mapping MAC → Raum
mac_to_room = self.derive_mac_to_room_mapping() # funktioniert jetzt
# 3. Prüfen
devices_status = []
for mac in macs:
room = mac_to_room.get(mac, "Unbekannt")
has_data = self.has_sensor_sent_data(mac, start, stop)
devices_status.append({
"mac_address": mac,
"room": room,
"availabil": "true" if has_data else "false"
})
return devices_status
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment