platform.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. # -*- coding: utf-8 -*-
  2. from enum import Enum
  3. from typing import Dict, Tuple
  4. import arrow
  5. import numpy as np
  6. from httpx import AsyncClient, URL
  7. from loguru import logger
  8. from app.core.config import settings
  9. from app.services.service import Service
  10. from app.utils.date import get_time_str, TIME_FMT
  11. from app.utils.math import round_half_up
  12. class InfoCode(str, Enum):
  13. temperature = 'Tdb'
  14. co2 = 'CO2'
  15. hcho = 'HCHO'
  16. pm2d5 = 'PM2d5'
  17. humidity = 'RH'
  18. supply_air_flow = 'SupplyAirFlow'
  19. supply_air_temperature = 'SupplyAirTemp'
  20. fan_speed = 'FanGear'
  21. class DataPlatformService(Service):
  22. def __init__(
  23. self,
  24. client: AsyncClient,
  25. project_id: str,
  26. server_settings=settings
  27. ):
  28. super(DataPlatformService, self).__init__(client)
  29. self._project_id = project_id
  30. self._base_url = URL(server_settings.PLATFORM_HOST)
  31. self._now_time = get_time_str()
  32. self._secret = server_settings.PLATFORM_SECRET
  33. def _common_parameters(self) -> Dict:
  34. return {'projectId': self._project_id, 'secret': self._secret}
  35. async def get_realtime_data(self, code: InfoCode, object_id: str) -> float:
  36. url = self._base_url.join('data-platform-3/hisdata/query_by_obj')
  37. params = self._common_parameters()
  38. start_time = get_time_str(60 * 60, flag='ago')
  39. payload = {
  40. 'criteria': {
  41. 'id': object_id,
  42. 'code': code.value,
  43. 'receivetime': {
  44. '$gte': start_time,
  45. '$lte': self._now_time,
  46. }
  47. }
  48. }
  49. raw_info = await self._post(url, params, payload)
  50. # value = np.NAN
  51. # if raw_info.get('Content'):
  52. try:
  53. latest_data = raw_info.get('Content')[-1].get('data')
  54. latest_time = raw_info.get('Content')[-1].get('receivetime')
  55. if arrow.get(latest_time, TIME_FMT).shift(minutes=15) < arrow.get(self._now_time, TIME_FMT):
  56. logger.info(f'delayed data - {object_id}: ({latest_time}, {latest_data})')
  57. value = round_half_up(latest_data, 2)
  58. except KeyError:
  59. value = np.NAN
  60. return value
  61. async def get_realtime_temperature(self, space_id: str) -> float:
  62. return await self.get_realtime_data(InfoCode.temperature, space_id)
  63. async def get_realtime_co2(self, space_id: str) -> float:
  64. return await self.get_realtime_data(InfoCode.co2, space_id)
  65. async def get_realtime_hcho(self, space_id: str) -> float:
  66. return await self.get_realtime_data(InfoCode.hcho, space_id)
  67. async def get_realtime_pm2d5(self, space_id: str) -> float:
  68. return await self.get_realtime_data(InfoCode.pm2d5, space_id)
  69. async def get_realtime_humidity(self, space_id: str) -> float:
  70. return await self.get_realtime_data(InfoCode.humidity, space_id)
  71. async def get_realtime_supply_air_flow(self, equipment_id: str) -> float:
  72. return await self.get_realtime_data(InfoCode.supply_air_flow, equipment_id)
  73. async def get_realtime_supply_air_temperature(self, equipment_id: str) -> float:
  74. return await self.get_realtime_data(InfoCode.supply_air_temperature, equipment_id)
  75. async def get_fan_speed(self, equipment_id: str) -> float:
  76. return await self.get_realtime_data(InfoCode.fan_speed, equipment_id)
  77. async def get_static_info(self, code: str, object_id: str):
  78. url = self._base_url.join('data-platform-3/object/batch_query')
  79. params = self._common_parameters()
  80. payload = {
  81. 'customInfo': True,
  82. 'criterias': [
  83. {
  84. 'id': object_id
  85. }
  86. ]
  87. }
  88. raw_info = await self._post(url, params, payload)
  89. try:
  90. info = raw_info['Content'][0]['infos'][code]
  91. except KeyError as e:
  92. logger.error(f'id: {object_id}, details: {e}')
  93. info = None
  94. return info
  95. async def get_air_flow_limit(self, equipment_id: str) -> Tuple[float, float]:
  96. lower = await self.get_static_info('MinAirFlow', equipment_id)
  97. upper = await self.get_static_info('MaxAirFlow', equipment_id)
  98. if not lower:
  99. lower = 150.0
  100. if not upper:
  101. upper = 2000.0
  102. return lower, upper