cleaned up and added some extra routes for zones

This commit is contained in:
Jurn Wubben 2025-08-26 16:32:08 +02:00
parent aefa4275d4
commit 33715cb34e
2 changed files with 155 additions and 80 deletions

232
app.py
View file

@ -10,7 +10,9 @@ from db import (
NetBriteBase, NetBriteBase,
NetBriteDB, NetBriteDB,
NetBritePublic, NetBritePublic,
ZoneBase,
ZoneDB, ZoneDB,
ZonePublic,
) )
DB_URL = "sqlite:///devices.db" DB_URL = "sqlite:///devices.db"
@ -38,78 +40,6 @@ active_devices: dict[int, nb.NetBrite] = {}
device_status: dict[int, bool] = {} device_status: dict[int, bool] = {}
# ---------- routes ----------
@app.post("/api/device", response_model=NetBritePublic)
def create_device(device: NetBriteBase, session: SessionDep):
if session.exec(
select(NetBriteDB).where(NetBriteDB.address == device.address)
).first():
raise HTTPException(400, "Device already exists")
db_device = NetBriteDB.model_validate(device)
session.add(db_device)
session.commit()
session.refresh(db_device)
load_device(db_device, session)
return db_device
@app.get("/api/devices", response_model=list[NetBritePublic])
def get_devices(session: SessionDep):
return session.exec(select(NetBriteDB)).all()
@app.post("/api/devices/{device_id}", response_model=NetBritePublic)
def update_device(device_id: int, session: SessionDep):
db_dev = session.get(NetBriteDB, device_id)
if not db_dev:
raise HTTPException(404, "Device not found")
return db_dev
# TODO: implement me
@app.post("/api/devices/{device_id}/reconnect")
def connect_device(device_id: int, session: SessionDep) -> dict[str, bool]:
db_dev = session.get(NetBriteDB, device_id)
if not db_dev:
raise HTTPException(404, "Device not found")
try:
active_devices[device_id] = nb.NetBrite(db_dev.address, db_dev.port)
device_status[device_id] = True
load_zones(session, device_id, active_devices[device_id])
return {"connected": True}
except nb.NetbriteConnectionException as exc:
device_status[device_id] = False
raise HTTPException(400, str(exc))
@app.delete("/api/devices/{device_id}")
def delete_device(device_id: int, session: SessionDep):
db_dev = session.get(NetBriteDB, device_id)
if not db_dev:
raise HTTPException(404, "Device not found")
delete: list[MessageDB | ZoneDB | NetBriteDB] = [db_dev]
for zone in db_dev.zones:
if zone.default_message != None:
delete.append(zone.default_message)
delete.append(zone)
if device_id in active_devices:
active_devices[device_id].sock.close()
del active_devices[device_id]
print(delete)
for i in delete:
session.delete(i)
session.commit()
return 200
# ---------- helper ---------- # ---------- helper ----------
def load_devices_from_db() -> None: def load_devices_from_db() -> None:
with Session(engine) as session: with Session(engine) as session:
@ -122,22 +52,31 @@ def load_device(device: NetBriteDB, session: SessionDep):
try: try:
active_devices[id] = nb.NetBrite(device.address, device.port) active_devices[id] = nb.NetBrite(device.address, device.port)
device_status[id] = True device_status[id] = True
load_zones(session, id, active_devices[id]) load_zones_id(session, id, active_devices[id])
except nb.NetbriteConnectionException as exc: except nb.NetbriteConnectionException as exc:
device_status[id] = False device_status[id] = False
print(f"Could not connect to {device.address}:{device.port}{exc}") print(f"Could not connect to {device.address}:{device.port}{exc}")
def load_zones(session: Session, device_id: int, net_dev: nb.NetBrite) -> None: def load_zones_id(session: Session, device_id: int, net_dev: nb.NetBrite):
zones: dict[str, nb.Zone] = {}
statement = select(ZoneDB).where(ZoneDB.netbrite_id == device_id) statement = select(ZoneDB).where(ZoneDB.netbrite_id == device_id)
zones = list(session.exec(statement))
load_zones(zones, net_dev)
for zone in session.exec(statement).all():
def load_zones(zones_in: list[ZoneDB], net_dev: nb.NetBrite) -> None:
zones: dict[str, nb.Zone] = {}
for zone in zones_in:
msg = zone.default_message msg = zone.default_message
default_msg = ( default_msg = (
nb.Message( nb.Message(
activation_delay=msg.activation_delay,
display_delay=msg.display_delay,
priority=msg.priority,
text=msg.text, text=msg.text,
ttl=msg.ttl,
) )
if msg if msg
else nb.Message(f"Zone {zone.name}") else nb.Message(f"Zone {zone.name}")
@ -165,13 +104,12 @@ def create_default_zone(session: Session, device_id: int) -> None:
name="0", name="0",
x=0, x=0,
y=0, y=0,
width=150, width=120,
height=7, height=7,
netbrite_id=device_id, netbrite_id=device_id,
) )
msg = MessageDB( msg = MessageDB(
text="{erase}Welcome", text="{erase}Welcome",
ttl=60,
) )
session.add(msg) session.add(msg)
session.add(zone) session.add(zone)
@ -182,3 +120,141 @@ def create_default_zone(session: Session, device_id: int) -> None:
zone.default_message_id = msg.id zone.default_message_id = msg.id
session.commit() session.commit()
# ---------- routes ----------
@app.post("/api/device", response_model=NetBritePublic)
def create_device(device: NetBriteBase, session: SessionDep):
if session.exec(
select(NetBriteDB).where(NetBriteDB.address == device.address)
).first():
raise HTTPException(400, "Device already exists")
db_device = NetBriteDB.model_validate(device)
session.add(db_device)
session.commit()
session.refresh(db_device)
load_device(db_device, session)
return db_device
@app.get("/api/devices", response_model=list[NetBritePublic])
def get_devices(session: SessionDep):
devices: list[NetBritePublic] = []
for device in session.exec(select(NetBriteDB)).all():
device = NetBritePublic.model_validate(
device, update={"active": device_status.get(device.id or 0) or False}
)
devices.append(device)
return devices # FIXME: implement active
@app.post("/api/devices/{device_id}", response_model=NetBritePublic)
def update_device(device_id: int, updated_device: NetBriteBase, session: SessionDep):
db_dev = session.get(NetBriteDB, device_id)
if not db_dev:
raise HTTPException(404, "Device not found")
db_dev.port = updated_device.port
db_dev.address = updated_device.address
return 200
# TODO: implement me
@app.post("/api/devices/{device_id}/reconnect")
def reconnect_device(device_id: int, session: SessionDep):
db_dev = session.get(NetBriteDB, device_id)
if not db_dev:
raise HTTPException(404, "Device not found")
try:
active_devices[device_id] = nb.NetBrite(db_dev.address, db_dev.port)
device_status[device_id] = True
load_zones_id(session, device_id, active_devices[device_id])
return 200
except nb.NetbriteConnectionException as exc:
device_status[device_id] = False
raise HTTPException(400, str(exc))
@app.delete("/api/devices/{device_id}")
def delete_device(device_id: int, session: SessionDep):
db_dev = session.get(NetBriteDB, device_id)
if not db_dev:
raise HTTPException(404, "Device not found")
delete: list[MessageDB | ZoneDB | NetBriteDB] = [db_dev]
for zone in db_dev.zones:
if zone.default_message != None:
delete.append(zone.default_message)
delete.append(zone)
if device_id in active_devices:
active_devices[device_id].sock.close()
del active_devices[device_id]
for i in delete:
session.delete(i)
session.commit()
return 200
@app.post("/api/devices/{device_id}/zones", response_model=ZonePublic)
def create_zone(device_id: int, body: ZoneBase, session: SessionDep):
device = session.get(NetBriteDB, device_id)
if not device:
raise HTTPException(404, "Device not found")
zone = ZoneDB.model_validate(body)
msg = MessageDB(
text="{erase}Welcome",
)
session.add(zone)
session.add(msg)
session.commit()
session.refresh(zone)
session.refresh(msg)
zone.default_message_id = msg.id
session.commit()
if not device.id in active_devices:
raise HTTPException(503, "Device not active")
try:
load_zones(device.zones, active_devices[device.id])
except nb.NetbriteTransferException:
raise HTTPException(503, "Device not active")
@app.get("/api/devices/{device_id}/zones", response_model=list[ZonePublic])
def get_zones(device_id: int, session: SessionDep):
device = session.get(NetBriteDB, device_id)
if not device:
raise HTTPException(404, "Device not found")
return device.zones
@app.delete(
"/api/zone/{zone_id}",
)
def delete_zone(zone_id: int, session: SessionDep):
zone = session.get(ZoneDB, zone_id)
if not zone:
raise HTTPException(404, "Zone not found")
message = zone.default_message
if message:
session.delete(message)
session.delete(zone)
session.commit()
return 200

3
db.py
View file

@ -22,7 +22,6 @@ class MessageDB(MessageBase, table=True):
class MessagePublic(MessageBase): class MessagePublic(MessageBase):
id: int id: int
zone: "ZoneDB"
# --- Device --- # --- Device ---
@ -75,4 +74,4 @@ class ZoneDB(ZoneBase, table=True):
class ZonePublic(ZoneBase): class ZonePublic(ZoneBase):
id: int id: int
default_message: MessagePublic default_message: MessagePublic
netbrite: NetBritePublic # netbrite: NetBritePublic