monitoring.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. from __future__ import annotations
  2. from sqlalchemy import desc, func, select
  3. from sqlalchemy.orm import Session
  4. from app.db.models.monitoring import (
  5. DataSource,
  6. Sensor,
  7. SensorReading,
  8. VentilationFacility,
  9. )
  10. from app.db.models.work_order import Alarm
  11. def monitoring_overview(db: Session, mine_id: str) -> dict[str, int]:
  12. return {
  13. "data_source_count": int(
  14. db.scalar(
  15. select(func.count(DataSource.id)).where(DataSource.mine_id == mine_id)
  16. )
  17. or 0
  18. ),
  19. "online_source_count": int(
  20. db.scalar(
  21. select(func.count(DataSource.id)).where(
  22. DataSource.mine_id == mine_id, DataSource.status == "online"
  23. )
  24. )
  25. or 0
  26. ),
  27. "sensor_count": int(
  28. db.scalar(select(func.count(Sensor.id)).where(Sensor.mine_id == mine_id)) or 0
  29. ),
  30. "online_sensor_count": int(
  31. db.scalar(
  32. select(func.count(Sensor.id)).where(
  33. Sensor.mine_id == mine_id, Sensor.status == "online"
  34. )
  35. )
  36. or 0
  37. ),
  38. "facility_count": int(
  39. db.scalar(
  40. select(func.count(VentilationFacility.id)).where(
  41. VentilationFacility.mine_id == mine_id
  42. )
  43. )
  44. or 0
  45. ),
  46. "abnormal_facility_count": int(
  47. db.scalar(
  48. select(func.count(VentilationFacility.id)).where(
  49. VentilationFacility.mine_id == mine_id,
  50. VentilationFacility.status != "normal",
  51. )
  52. )
  53. or 0
  54. ),
  55. "open_alarm_count": int(
  56. db.scalar(
  57. select(func.count(Alarm.id)).where(
  58. Alarm.mine_id == mine_id, Alarm.status == "open"
  59. )
  60. )
  61. or 0
  62. ),
  63. "high_alarm_count": int(
  64. db.scalar(
  65. select(func.count(Alarm.id)).where(
  66. Alarm.mine_id == mine_id,
  67. Alarm.status == "open",
  68. Alarm.level == "high",
  69. )
  70. )
  71. or 0
  72. ),
  73. }
  74. def list_data_sources(db: Session, mine_id: str) -> list[DataSource]:
  75. return list(
  76. db.scalars(
  77. select(DataSource)
  78. .where(DataSource.mine_id == mine_id)
  79. .order_by(DataSource.name)
  80. ).all()
  81. )
  82. def list_sensors(
  83. db: Session,
  84. mine_id: str,
  85. sensor_type: str | None = None,
  86. ) -> list[Sensor]:
  87. statement = select(Sensor).where(Sensor.mine_id == mine_id)
  88. if sensor_type:
  89. statement = statement.where(Sensor.sensor_type == sensor_type)
  90. return list(db.scalars(statement.order_by(Sensor.code)).all())
  91. def get_sensor(db: Session, sensor_id: str) -> Sensor | None:
  92. return db.get(Sensor, sensor_id)
  93. def list_readings(
  94. db: Session,
  95. sensor_id: str,
  96. *,
  97. limit: int = 200,
  98. ) -> list[SensorReading]:
  99. return list(
  100. db.scalars(
  101. select(SensorReading)
  102. .where(SensorReading.sensor_id == sensor_id)
  103. .order_by(desc(SensorReading.measured_at))
  104. .limit(limit)
  105. ).all()
  106. )
  107. def list_facilities(db: Session, mine_id: str) -> list[VentilationFacility]:
  108. return list(
  109. db.scalars(
  110. select(VentilationFacility)
  111. .where(VentilationFacility.mine_id == mine_id)
  112. .order_by(VentilationFacility.code)
  113. ).all()
  114. )
  115. def list_alarms(
  116. db: Session,
  117. mine_id: str,
  118. *,
  119. status: str | None = None,
  120. limit: int = 100,
  121. ) -> list[Alarm]:
  122. statement = select(Alarm).where(Alarm.mine_id == mine_id)
  123. if status:
  124. statement = statement.where(Alarm.status == status)
  125. return list(
  126. db.scalars(statement.order_by(desc(Alarm.occurred_at)).limit(limit)).all()
  127. )