transfer.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. # -*- coding: utf-8 -*-
  2. from enum import Enum
  3. from typing import Dict, List
  4. import arrow
  5. import numpy as np
  6. import pandas as pd
  7. from httpx import AsyncClient, URL
  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 Season(str, Enum):
  13. cooling = 'Cooling'
  14. heating = 'Warm'
  15. transition = 'Transition'
  16. class SpaceInfoService(Service):
  17. def __init__(
  18. self,
  19. client: AsyncClient,
  20. project_id: str,
  21. space_id: str,
  22. server_settings=settings
  23. ) -> None:
  24. super(SpaceInfoService, self).__init__(client)
  25. self._project_id = project_id
  26. self._space_id = space_id
  27. self._base_url = URL(server_settings.TRANSFER_HOST)
  28. self._now_time = get_time_str()
  29. def _common_parameters(self) -> Dict:
  30. return {'projectId': self._project_id, 'spaceId': self._space_id}
  31. async def is_customized(self) -> bool:
  32. url = self._base_url.join('duoduo-service/custom-service/custom/timetarget')
  33. time_str = arrow.get(arrow.get(self._now_time, TIME_FMT).shift(minutes=15).timestamp
  34. // 900 * 900).strftime('%Y%m%d%H%M%S')
  35. params = {
  36. 'projectId': self._project_id,
  37. 'objectId': self._space_id,
  38. 'timepoint': time_str,
  39. }
  40. raw_info = await self._get(url, params)
  41. flag = False
  42. if raw_info.get('data'):
  43. flag = True
  44. return flag
  45. async def is_temporary(self) -> bool:
  46. url = self._base_url.join('duoduo-service/transfer/environment/temp/target')
  47. params = self._common_parameters()
  48. params.update({'time': self._now_time})
  49. raw_info = await self._get(url, params)
  50. flag = False
  51. if raw_info.get('flag') == 1:
  52. flag = True
  53. return flag
  54. async def get_feedback(self, wechat_time: str) -> Dict:
  55. url = self._base_url.join('duoduo-service/transfer/environment/feedbackCount')
  56. params = self._common_parameters()
  57. params.update({'time': wechat_time})
  58. raw_info = await self._get(url, params)
  59. meaning_dict = {
  60. 'Id1': 'a little cold',
  61. 'Id2': 'so cold',
  62. 'Id3': 'a little hot',
  63. 'Id4': 'so hot',
  64. 'Id5': 'noisy or blowy',
  65. 'Id6': 'so stuffy',
  66. 'Id7': 'more sunshine',
  67. 'Id8': 'less sunshine',
  68. 'Id9': 'send a repairman',
  69. 'Id10': 'switch off',
  70. 'Id11': 'nice',
  71. 'Id12': 'switch on',
  72. }
  73. feedback_dic = {meaning_dict.get(k): v for k, v in raw_info.items() if k != 'result'}
  74. return feedback_dic
  75. async def get_custom_target(self) -> pd.DataFrame:
  76. url = self._base_url.join('duoduo-service/transfer/environment/target')
  77. params = self._common_parameters()
  78. params.update({'date': arrow.get(self._now_time, TIME_FMT).date().strftime('%Y%m%d')})
  79. raw_info = await self._get(url, params)
  80. try:
  81. custom_target_df = pd.DataFrame(raw_info.get('data'))
  82. custom_target_df.set_index('time', inplace=True)
  83. except KeyError:
  84. custom_target_df = pd.DataFrame()
  85. return custom_target_df
  86. async def get_current_temperature_target(self) -> float:
  87. current_targets = await self.get_custom_target()
  88. temp = arrow.get(self._now_time, TIME_FMT).shift(minutes=15).timestamp // (15 * 60) * (15 * 60)
  89. next_quarter_minutes = arrow.get(temp).time().strftime('%H%M%S')
  90. try:
  91. current_lower_target = current_targets['temperatureMin'].loc[next_quarter_minutes]
  92. current_upper_target = current_targets['temperatureMax'].loc[next_quarter_minutes]
  93. except KeyError:
  94. current_lower_target, current_upper_target = np.NAN, np.NAN
  95. return round_half_up((current_lower_target + current_upper_target) / 2, 2)
  96. async def env_database_set(self, form: str, value: float) -> None:
  97. url = self._base_url.join('duoduo-service/transfer/environment/hispoint/set')
  98. params = self._common_parameters()
  99. time_str = arrow.get(arrow.get(self._now_time, TIME_FMT).timestamp // 900 * 900).strftime('%Y%m%d%H%M%S')
  100. params.update({'time': time_str, 'type': form, 'value': value})
  101. await self._get(url, params)
  102. async def env_database_get(self) -> Dict[str, pd.DataFrame]:
  103. url = self._base_url.join('duoduo-service/transfer/environment/hispoint/get')
  104. params = self._common_parameters()
  105. params.update({'date': arrow.get(self._now_time, TIME_FMT).date().strftime('%Y%m%d')})
  106. raw_info = await self._get(url, params)
  107. result = {}
  108. if raw_info.get('result') == 'success':
  109. for k, v in raw_info.items():
  110. if k != 'result':
  111. if len(v) > 0:
  112. temp = {}
  113. data = np.array(v)
  114. temp.update({'timestamp': data[:, 0]})
  115. temp.update({'value': data[:, 1].astype(np.float)})
  116. result.update({k: pd.DataFrame(temp)})
  117. else:
  118. result.update({k: pd.DataFrame()})
  119. return result
  120. async def set_custom_target(self, form: str, target_value: Dict[str, List[float]], flag: str = '1') -> None:
  121. url = self._base_url.join('duoduo-service/transfer/environment/target/setting')
  122. params = {
  123. 'projectId': self._project_id,
  124. 'spaceId': self._space_id,
  125. 'timepoint': self._now_time,
  126. 'type': form,
  127. 'flag': flag
  128. }
  129. await self._post(url, params=params, payload=target_value)
  130. async def set_temporary_custom(self) -> None:
  131. url = self._base_url.join('duoduo-service/transfer/environment/setServiceFlag')
  132. params = self._common_parameters()
  133. params.update({'time': self._now_time})
  134. await self._get(url, params)
  135. async def get_equipment(self) -> List[dict]:
  136. url = self._base_url.join('duoduo-service/object-service/object/equipment/findForServe')
  137. params = self._common_parameters()
  138. raw_info = await self._post(url, params)
  139. result = []
  140. for eq in raw_info.get('data'):
  141. result.append({'id': eq.get('id'), 'category': eq.get('equipmentCategory')})
  142. return result
  143. class Duoduo(Service):
  144. def __init__(self, client: AsyncClient, project_id: str, server_settings=settings):
  145. super(Duoduo, self).__init__(client)
  146. self._project_id = project_id
  147. self._base_url = URL(server_settings.TRANSFER_HOST)
  148. self._now_time = get_time_str()
  149. async def get_season(self) -> Season:
  150. url = self._base_url.join('duoduo-service/transfer/environment/getSeasonType')
  151. params = {
  152. 'projectId': self._project_id,
  153. 'date': self._now_time,
  154. }
  155. raw_info = await self._get(url, params)
  156. return Season(raw_info.get('data'))
  157. async def get_fill_rate(self):
  158. url = self._base_url.join('duoduo-service/review-service/space/report/quarter/query')
  159. payload = {
  160. 'criteria': {
  161. 'projectId': self._project_id,
  162. 'date': arrow.get(self._now_time, TIME_FMT).date().strftime('%Y%m%d')
  163. },
  164. 'orders': [
  165. {
  166. 'column': 'time',
  167. 'asc': False
  168. }
  169. ],
  170. 'page': 1,
  171. 'size': 1
  172. }
  173. raw_info = await self._post(url, payload=payload)
  174. try:
  175. content = raw_info.get('content')[-1]
  176. hot_rate = (content.get('hotNum')
  177. / (content.get('normalNum') + content.get('hotNum') + content.get('coldNum')))
  178. except KeyError and ZeroDivisionError:
  179. hot_rate = 0.0
  180. return hot_rate
  181. async def get_space_by_equipment(self, equipment_id: str) -> List[dict]:
  182. url = self._base_url.join('duoduo-service/object-service/object/space/findForServe')
  183. params = {
  184. 'projectId': self._project_id,
  185. 'objectId': equipment_id
  186. }
  187. raw_info = await self._post(url, params)
  188. result = []
  189. for sp in raw_info.get('data'):
  190. if sp.get('isControlled'):
  191. result.append({'id': sp.get('id')})
  192. return result
  193. async def get_system_by_equipment(self, equipment_id: str) -> List:
  194. url = self._base_url.join('duoduo-service/object-service/object/system/findForCompose')
  195. params = {
  196. 'projectId': self._project_id,
  197. 'equipmentId': equipment_id
  198. }
  199. raw_info = await self._post(url, params)
  200. system_list = []
  201. for sy in raw_info.get('data'):
  202. system_list.append({'id': sy.get('id')})
  203. return system_list
  204. async def get_day_type(self) -> Dict:
  205. url = self._base_url.join('duoduo-service/custom-service/custom/getDateInfo')
  206. params = {
  207. 'projectId': self._project_id,
  208. 'date': arrow.get(self._now_time, TIME_FMT).date().strftime('%Y%m%d')
  209. }
  210. raw_info = await self._get(url, params)
  211. result = {
  212. 'day_type': raw_info.get('dayType'),
  213. 'season': raw_info.get('seasonType')
  214. }
  215. return result
  216. async def query_device_virtual_data(self, device_id: str, info_code: str) -> float:
  217. url = self._base_url.join('duoduo-service/review-service/equipment/order/query')
  218. payload = {
  219. 'criteria': {
  220. 'projectId': self._project_id,
  221. 'objectId': device_id,
  222. 'date': arrow.get(self._now_time, TIME_FMT).date().strftime('%Y%m%d'),
  223. 'funcId': info_code
  224. }
  225. }
  226. raw_info = await self._post(url, payload=payload)
  227. try:
  228. latest_data = raw_info.get('data')[-1].get('value')
  229. latest_time = raw_info.get('data')[-1].get('realTime')
  230. if arrow.get(latest_time, TIME_FMT).shift(minutes=15) < arrow.get(self._now_time, TIME_FMT):
  231. value = np.NAN
  232. else:
  233. value = latest_data
  234. except KeyError:
  235. value = np.NAN
  236. return value