retrieved return events working but bug with return to be fixed

This commit is contained in:
GotthardG
2024-11-26 17:41:01 +01:00
parent fc8bb8d200
commit fbb868e255
3 changed files with 142 additions and 62 deletions

View File

@ -25,45 +25,67 @@ def calculate_time_until_refill(last_refill: Optional[datetime], refill_interval
@router.post("/dewars/retrieve", response_model=DewarSchema)
async def retrieve_dewar(data: LogisticsEventCreate, db: Session = Depends(get_db)):
logger.info(f"Received data for retrieve_dewar: {data}")
async def retrieve_or_return_dewar(data: LogisticsEventCreate, db: Session = Depends(get_db)):
logger.info(f"Received data for retrieve_or_return_dewar: {data}")
dewar = db.query(DewarModel).filter(DewarModel.unique_id == data.dewar_qr_code).first()
if not dewar:
raise HTTPException(status_code=404, detail="Dewar not found")
new_event = LogisticsEventModel(
dewar_id=dewar.id,
slot_id=None,
event_type="retrieved",
timestamp=datetime.now(),
)
# Fetch the associated slot if it exists
slot = db.query(SlotModel).filter(SlotModel.qr_code == data.location_qr_code).first()
if not slot:
raise HTTPException(status_code=404, detail="Slot not found")
# Check the last event for this dewar to determine the next action
last_event = db.query(LogisticsEventModel).filter(
LogisticsEventModel.dewar_id == dewar.id
).order_by(LogisticsEventModel.timestamp.desc()).first()
if last_event and last_event.event_type == "retrieved":
# Create a 'returned' event if the last event was 'retrieved'
new_event = LogisticsEventModel(
dewar_id=dewar.id,
slot_id=slot.id,
event_type="returned",
timestamp=datetime.now(),
)
dewar.last_retrieved_timestamp = None
# Update the location to the slot
slot.dewar_unique_id = dewar.unique_id
slot.occupied = True
db.commit()
logger.info(f"Dewar {dewar.unique_id} returned to slot {slot.qr_code} successfully.")
else:
# Create a 'retrieved' event
new_event = LogisticsEventModel(
dewar_id=dewar.id,
slot_id=None,
event_type="retrieved",
timestamp=datetime.now(),
)
dewar.last_retrieved_timestamp = new_event.timestamp.isoformat()
logger.info(f"Dewar {dewar.unique_id} retrieved successfully.")
db.add(new_event)
db.commit()
db.refresh(dewar)
# Get the last retrieved event for the dewar
last_retrieved_event = db.query(LogisticsEventModel).filter(
LogisticsEventModel.dewar_id == dewar.id,
LogisticsEventModel.event_type == "retrieved"
).order_by(LogisticsEventModel.timestamp.desc()).first()
if last_retrieved_event:
dewar.last_retrieved_timestamp = last_retrieved_event.timestamp.isoformat()
logger.info(f"Last retrieved event timestamp for dewar {dewar.unique_id}: "
f"{dewar.last_retrieved_timestamp}")
else:
dewar.last_retrieved_timestamp = None
logger.info(f"No retrieved event found for dewar {dewar.unique_id}")
return dewar
@router.post("/dewar/scan", response_model=dict)
async def scan_dewar(event_data: LogisticsEventCreate, db: Session = Depends(get_db)):
logger.info(f"Received event data: {event_data}")
dewar_qr_code = event_data.dewar_qr_code
location_qr_code = event_data.location_qr_code
transaction_type = event_data.transaction_type
if not dewar_qr_code or not dewar_qr_code.strip():
logger.error("Dewar QR Code is null or empty")
raise HTTPException(status_code=422, detail="Dewar QR Code cannot be null or empty")
dewar = db.query(DewarModel).filter(DewarModel.unique_id == dewar_qr_code).first()
if not dewar:
raise HTTPException(status_code=404, detail="Dewar not found")
@ -72,20 +94,22 @@ async def scan_dewar(event_data: LogisticsEventCreate, db: Session = Depends(get
if transaction_type == 'incoming':
if not slot or slot.occupied:
logger.error(f"Slot not found or already occupied: {slot}")
raise HTTPException(status_code=400, detail="Slot not found or already occupied")
slot.dewar_unique_id = dewar.unique_id
slot.occupied = True
elif transaction_type == 'outgoing':
if not slot or not slot.occupied or slot.dewar_unique_id != dewar.unique_id:
logger.error(f"Slot not found or dewar not associated with slot: {slot}")
raise HTTPException(status_code=400, detail="Slot not found or dewar not associated with slot")
slot.dewar_unique_id = None
slot.occupied = False
elif transaction_type == 'beamline':
if not slot:
logger.error(f"Beamline location not found: {location_qr_code}")
raise HTTPException(status_code=400, detail="Beamline location not found")
dewar.beamline_location = location_qr_code
# Create a logistics event
log_event(db, dewar.id, slot.id if slot else None, transaction_type)
db.commit()
@ -100,14 +124,18 @@ async def get_all_slots(db: Session = Depends(get_db)):
for slot in slots:
time_until_refill = None
retrievedTimestamp = None
beamlineLocation = None
at_beamline = False
retrieved = False
if slot.dewar_unique_id:
# Calculate time until refill
last_refill_event = db.query(LogisticsEventModel) \
.join(DewarModel, DewarModel.id == LogisticsEventModel.dewar_id) \
.filter(
DewarModel.unique_id == slot.dewar.unique_id,
LogisticsEventModel.event_type == "refill"
) \
DewarModel.unique_id == slot.dewar.unique_id,
LogisticsEventModel.event_type == "refill"
) \
.order_by(LogisticsEventModel.timestamp.desc()) \
.first()
@ -121,27 +149,30 @@ async def get_all_slots(db: Session = Depends(get_db)):
last_retrieved_event = db.query(LogisticsEventModel) \
.join(DewarModel, DewarModel.id == LogisticsEventModel.dewar_id) \
.filter(
DewarModel.unique_id == slot.dewar.unique_id,
LogisticsEventModel.event_type == "retrieved"
) \
DewarModel.unique_id == slot.dewar.unique_id,
LogisticsEventModel.event_type == "retrieved"
) \
.order_by(LogisticsEventModel.timestamp.desc()) \
.first()
if last_retrieved_event:
retrievedTimestamp = last_retrieved_event.timestamp.isoformat()
retrieved = True
# Determine if the dewar is at the beamline
at_beamline = False
if slot.dewar_unique_id:
at_beamline_event = db.query(LogisticsEventModel) \
# Determine the last event excluding refills
last_event = db.query(LogisticsEventModel) \
.join(DewarModel, DewarModel.id == LogisticsEventModel.dewar_id) \
.filter(
DewarModel.unique_id == slot.dewar.unique_id,
LogisticsEventModel.event_type == "beamline"
) \
DewarModel.unique_id == slot.dewar.unique_id,
LogisticsEventModel.event_type != "refill"
) \
.order_by(LogisticsEventModel.timestamp.desc()) \
.first()
at_beamline = bool(at_beamline_event)
if last_event:
associated_slot = db.query(SlotModel).filter(SlotModel.id == last_event.slot_id).first()
beamlineLocation = associated_slot.label if associated_slot else None
at_beamline = last_event.event_type == "beamline"
slot_data = SlotSchema(
id=slot.id,
@ -154,12 +185,14 @@ async def get_all_slots(db: Session = Depends(get_db)):
dewar_name=slot.dewar.dewar_name if slot.dewar else None,
time_until_refill=time_until_refill,
at_beamline=at_beamline,
retrieved=retrieved,
retrievedTimestamp=retrievedTimestamp,
beamlineLocation=beamlineLocation,
)
logger.info(f"Dewar retrieved on the: {retrievedTimestamp}")
logger.info(f"Dewar retrieved: {retrieved}")
logger.info(f"Dewar at: {beamlineLocation}")
slots_with_refill_time.append(slot_data)
return slots_with_refill_time

View File

@ -288,7 +288,9 @@ class SlotSchema(BaseModel):
dewar_name: Optional[str]
time_until_refill: Optional[int]
at_beamline: Optional[bool]
retrieved: Optional[bool]
retrievedTimestamp: Optional[str]
beamlineLocation: Optional[str]
class Config:
from_attributes = True