series_service.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. """PKS 原始采样曲线:按设备与时间窗口读取 YSJ_5 / YSJ_10 / YSJ_11。
  2. 只取运行样本(``YSJ_41 > 0``);停机造成的长时间空档插入空点,让曲线断开。
  3. """
  4. from datetime import timedelta
  5. from typing import Any
  6. from db import connect
  7. GAP = timedelta(seconds=60)
  8. def _num(value: Any) -> float | None:
  9. """0(传感器掉点/停机残留)视为无效,置空以断开曲线。"""
  10. try:
  11. number = float(value) if value is not None else None
  12. except (TypeError, ValueError):
  13. return None
  14. if number is None or number <= 0:
  15. return None
  16. return number
  17. def query_recent_series(device_code: str, hours: int = 6) -> dict[str, Any]:
  18. """数据库中最新的 ``hours`` 小时实时数据(以该设备最新采样时间为终点)。"""
  19. connection = connect()
  20. try:
  21. with connection.cursor() as cursor:
  22. cursor.execute(
  23. "SELECT MAX(sample_time) AS latest FROM pks_long_sample WHERE device_code = %s",
  24. (device_code,),
  25. )
  26. row = cursor.fetchone()
  27. finally:
  28. connection.close()
  29. latest = row["latest"] if row else None
  30. if latest is None:
  31. return {
  32. "device_code": device_code, "start": None, "end": None, "count": 0,
  33. "times": [], "oil": [], "coupling": [], "chain": [],
  34. }
  35. fmt = "%Y-%m-%d %H:%M:%S"
  36. start = (latest - timedelta(hours=hours)).strftime(fmt)
  37. return query_series(device_code, start, latest.strftime(fmt))
  38. def query_series(device_code: str, start: str, end: str) -> dict[str, Any]:
  39. connection = connect()
  40. try:
  41. with connection.cursor() as cursor:
  42. cursor.execute(
  43. """
  44. SELECT sample_time, YSJ_5, YSJ_10, YSJ_11
  45. FROM pks_long_sample
  46. WHERE device_code = %s AND sample_time >= %s AND sample_time <= %s
  47. AND YSJ_41 > 0
  48. ORDER BY sample_time
  49. """,
  50. (device_code, start, end),
  51. )
  52. rows = cursor.fetchall()
  53. finally:
  54. connection.close()
  55. times: list[str] = []
  56. oil: list[float | None] = []
  57. coupling: list[float | None] = []
  58. chain: list[float | None] = []
  59. previous = None
  60. for row in rows:
  61. moment = row["sample_time"]
  62. if previous is not None and (moment - previous) > GAP:
  63. middle = previous + (moment - previous) / 2
  64. times.append(middle.strftime("%Y-%m-%d %H:%M:%S"))
  65. oil.append(None)
  66. coupling.append(None)
  67. chain.append(None)
  68. times.append(moment.strftime("%Y-%m-%d %H:%M:%S"))
  69. oil.append(_num(row["YSJ_5"]))
  70. coupling.append(_num(row["YSJ_10"]))
  71. chain.append(_num(row["YSJ_11"]))
  72. previous = moment
  73. return {
  74. "device_code": device_code,
  75. "start": start,
  76. "end": end,
  77. "count": len(times),
  78. "times": times,
  79. "oil": oil,
  80. "coupling": coupling,
  81. "chain": chain,
  82. }