cloudpss 4.1.1b8__py3-none-any.whl → 4.5.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. cloudpss/__init__.py +2 -3
  2. cloudpss/asyncio/__init__.py +8 -0
  3. cloudpss/asyncio/job/__init__.py +5 -0
  4. cloudpss/asyncio/job/job.py +116 -0
  5. cloudpss/asyncio/job/messageStreamReceiver.py +121 -0
  6. cloudpss/asyncio/job/messageStreamSender.py +45 -0
  7. cloudpss/asyncio/model/__init__.py +5 -0
  8. cloudpss/asyncio/model/model.py +257 -0
  9. cloudpss/asyncio/model/revision.py +41 -0
  10. cloudpss/asyncio/model/topology.py +34 -0
  11. cloudpss/asyncio/utils/__init__.py +6 -0
  12. cloudpss/{utils → asyncio/utils}/httpAsyncRequest.py +2 -2
  13. cloudpss/dslab/dataManageModel.py +19 -0
  14. cloudpss/dslab/dslab.py +35 -9
  15. cloudpss/function/functionExecution.py +74 -5
  16. cloudpss/ieslab/DataManageModel.py +144 -9
  17. cloudpss/ieslab/EvaluationModel.py +80 -9
  18. cloudpss/ieslab/IESLabOpt.py +235 -0
  19. cloudpss/ieslab/IESLabPlan.py +82 -4
  20. cloudpss/ieslab/IESLabSimulation.py +59 -32
  21. cloudpss/ieslab/PlanModel.py +222 -18
  22. cloudpss/ieslab/__init__.py +2 -1
  23. cloudpss/job/TemplateCompiler.py +273 -0
  24. cloudpss/job/TemplateManager.py +37 -0
  25. cloudpss/job/job.py +136 -141
  26. cloudpss/job/jobReceiver.py +8 -2
  27. cloudpss/job/messageStreamReceiver.py +42 -99
  28. cloudpss/job/messageStreamSender.py +5 -42
  29. cloudpss/job/{view/EMTView.py → result/EMTResult.py} +57 -14
  30. cloudpss/job/result/IESLabSimulationResult.py +5 -0
  31. cloudpss/job/result/IESLabTypicalDayResult.py +134 -0
  32. cloudpss/job/{view/IESView.py → result/IESResult.py} +7 -5
  33. cloudpss/job/{view/PowerFlowView.py → result/PowerFlowResult.py} +2 -2
  34. cloudpss/job/result/__init__.py +40 -0
  35. cloudpss/job/{view/view.py → result/result.py} +38 -8
  36. cloudpss/model/implements/diagram.py +140 -0
  37. cloudpss/model/jobDefinitions.py +6 -6
  38. cloudpss/model/model.py +245 -226
  39. cloudpss/model/revision.py +30 -35
  40. cloudpss/model/topology.py +26 -15
  41. cloudpss/runner/IESLabEvaluationResult.py +14 -6
  42. cloudpss/runner/IESLabPlanResult.py +91 -35
  43. cloudpss/runner/IESLabTypicalDayResult.py +62 -50
  44. cloudpss/runner/MessageStreamReceiver.py +5 -100
  45. cloudpss/runner/result.py +6 -1
  46. cloudpss/runner/runner.py +97 -53
  47. cloudpss/utils/IO.py +3 -1
  48. cloudpss/utils/graphqlUtil.py +3 -2
  49. cloudpss/utils/httprequests.py +19 -10
  50. cloudpss/version.py +1 -1
  51. {cloudpss-4.1.1b8.dist-info → cloudpss-4.5.13.dist-info}/METADATA +2 -2
  52. cloudpss-4.5.13.dist-info/RECORD +80 -0
  53. cloudpss/job/jobMachine.py +0 -11
  54. cloudpss/job/jobPolicy.py +0 -129
  55. cloudpss/job/jobQueue.py +0 -14
  56. cloudpss/job/jobTres.py +0 -6
  57. cloudpss/job/view/IESLabSimulationView.py +0 -5
  58. cloudpss/job/view/IESLabTypicalDayView.py +0 -27
  59. cloudpss/job/view/__init__.py +0 -42
  60. cloudpss-4.1.1b8.dist-info/RECORD +0 -71
  61. /cloudpss/{utils → asyncio/utils}/AsyncIterable.py +0 -0
  62. {cloudpss-4.1.1b8.dist-info → cloudpss-4.5.13.dist-info}/WHEEL +0 -0
  63. {cloudpss-4.1.1b8.dist-info → cloudpss-4.5.13.dist-info}/top_level.txt +0 -0
@@ -9,54 +9,51 @@ class IESLabTypicalDayResult(Result):
9
9
  Result.__init__(self, *args, **kwargs)
10
10
  self.__plotIndex = 0
11
11
  self.__typicalIndex = 0
12
- self.__type_list =['电负荷', '热负荷','冷负荷','总辐射','散射辐射', '直射辐射', '天顶角', '环境温度', '土壤温度', '10m风速', '50m风速', '建筑物高度风速', '风机高度风速']
13
- self.result = {'TypicalMonth': [],'TypicalDay': []}
14
- for i in range(12):
15
- self.result['TypicalMonth'].append({'月份': int, '持续天数': [],'电负荷': [], '热负荷': [],'冷负荷':[],'总辐射': [],'直射辐射': [],'散射辐射': [],'天顶角': [],
16
- '环境温度': [], '土壤温度': [], '建筑物高度风速': [], '风机高度风速': [],'10m风速': [], '50m风速': [] })
17
-
12
+ self.__type_list =['总辐射','散射辐射', '直射辐射','天顶角', '环境温度', '湿球温度','土壤温度', '10m风速', '50m风速','电负荷', '热负荷','冷负荷','氢负荷']
13
+ self.__map_load = { 'maxElectricalLoad':'电负荷', 'maxHeatLoad':'热负荷','maxCoolLoad':'冷负荷','maxHydrogenLoad':'氢负荷' }
14
+ self.result = {'TypicalMonth': [{'月份': int,'持续天数': [],**{key: [] for key in self.__type_list}} for i in range(12)],'TypicalDay': []}
18
15
 
19
16
  def __readPlotResult(self):
20
17
  length = self.db.getMessageLength()
21
18
  if (length > self.__plotIndex):
22
19
  for num in range(self.__plotIndex, length):# update TypicalMonth
23
20
  val = self.db.getMessage(num)
24
- if val['type'] == 'plot':
25
- key_list = re.split('-month',val['key'])#分别为类型和月份
26
- # print(key_list)
27
- self.result['TypicalMonth'][int(key_list[1])-1]['月份'] = int(key_list[1])
28
- if key_list[0] in ['总辐射','散射辐射']:#从第一类数据中分析每个月各个典型日的天数
29
- typicalNum = len(val['data']['traces'])
30
- for i in range(typicalNum):
31
- self.result['TypicalMonth'][int(key_list[1])-1]['持续天数'].append(int(re.findall('\d+',val['data']['traces'][i]['name'])[1]))
32
- # 每个月各类型数据的各个典型日的数据,由于部分月份可能没有电冷热负荷,某月的某个典型日可能缺少冷热负荷
33
- for i in range(typicalNum):
34
- self.result['TypicalMonth'][int(key_list[1])-1][key_list[0]].append([])
35
- for i in range(len(val['data']['traces'])):
36
- self.result['TypicalMonth'][int(key_list[1])-1][key_list[0]][int(re.findall('\d+',val['data']['traces'][i]['name'])[0])-1] = copy.deepcopy(val['data']['traces'][i]['y'])
37
- self.__plotIndex = length
21
+ if val['type'] == 'plot':# 每个月各类型数据的各个典型日的数据,由于部分月份可能没有电冷热负荷,某月的某个典型日可能缺少冷热负荷
22
+ key_re = re.split('-month',val['key'])#格式为:散射辐射-month1,re后分别为类型和月份
23
+ typical_month_m = self.result['TypicalMonth'][int(key_re[1])-1]
24
+ typical_month_m['月份'] = int(key_re[1])
25
+ val_data_traces = val['data']['traces']
26
+ #val['data']['traces'][i]['name']格式为:典型日1-共31天,re正则后[0]为典型日顺序,[1]为持续天数
27
+ typicalNum = int(re.findall('\d+',val_data_traces[-1]['name'])[0])
28
+ for i in range(typicalNum):#取该类型的最后一个典型日顺序,当该类型缺少后排典型日时,小于实际典型日数量
29
+ typical_month_m[key_re[0]].append([])
30
+ if key_re[0] == '环境温度':#各类版本气象数据均有环境温度数据,其典型日数量为实际数量
31
+ typical_month_m['持续天数'].append(int(re.findall('\d+',val_data_traces[i]['name'])[1]))
32
+ # 当前排典型日缺少数据时,该类型数据为空list[];当后排典型日缺少数据时,该类型数据为空
33
+ for i in range(len(val_data_traces)):
34
+ typical_month_m[key_re[0]][int(re.findall('\d+',val_data_traces[i]['name'])[0])-1] = copy.deepcopy(val_data_traces[i]['y'])
35
+
38
36
  # update TypicalDay based on TypicalMonth
39
37
  for m in range(12):
40
- for i in range(len(self.result['TypicalMonth'][m]['持续天数'])):
41
- self.result['TypicalDay'].append({'info':{'typicalDayID': int, 'name': str, 'duration': int, 'maxElectricalLoad': 0.0, 'maxHeatLoad': 0.0, 'maxCoolLoad': 0.0},
42
- 'data': {'电负荷': [], '热负荷': [],'冷负荷':[],'总辐射': [],'直射辐射': [],'散射辐射': [],'天顶角': [],
43
- '环境温度': [], '土壤温度': [], '建筑物高度风速': [], '风机高度风速': [],'10m风速': [], '50m风速': []}})
44
- self.result['TypicalDay'][-1]['info']['typicalDayID'] = self.__typicalIndex
45
- self.result['TypicalDay'][-1]['info']['name'] = str(m+1) + '月典型日' + str(i+1)
46
- self.result['TypicalDay'][-1]['info']['duration'] = self.result['TypicalMonth'][m]['持续天数'][i]
47
- if self.result['TypicalMonth'][m]['电负荷']:
48
- if self.result['TypicalMonth'][m]['电负荷'][i]:
49
- self.result['TypicalDay'][-1]['info']['maxElectricalLoad'] = max(self.result['TypicalMonth'][m]['电负荷'][i])
50
- if self.result['TypicalMonth'][m]['热负荷']:
51
- if self.result['TypicalMonth'][m]['热负荷'][i]:
52
- self.result['TypicalDay'][-1]['info']['maxHeatLoad'] = max(self.result['TypicalMonth'][m]['热负荷'][i])
53
- if self.result['TypicalMonth'][m]['冷负荷']:
54
- if self.result['TypicalMonth'][m]['冷负荷'][i]:
55
- self.result['TypicalDay'][-1]['info']['maxCoolLoad'] = max(self.result['TypicalMonth'][m]['冷负荷'][i])
38
+ typical_month_m = self.result['TypicalMonth'][m]
39
+ typical_month_m_day = len(typical_month_m['持续天数'])
40
+ for i in range(typical_month_m_day):
41
+ self.result['TypicalDay'].append({'info':{'typicalDayID': int, 'name': str, 'duration': int, **{key: 0.0 for key in self.__map_load}},
42
+ 'data': {**{key: [] for key in self.__type_list}}})
43
+ typical_day_index = self.result['TypicalDay'][self.__typicalIndex]
44
+ typical_day_index['info']['typicalDayID'] = self.__typicalIndex
45
+ typical_day_index['info']['name'] = str(m+1) + '月典型日' + str(i+1)
46
+ typical_day_index['info']['duration'] = typical_month_m['持续天数'][i]
47
+ for key,value in self.__map_load.items():
48
+ # 分别处理该典型日无此类型负荷数据,缺少后序典型日,缺少前序典型日的情况
49
+ if typical_month_m.get(value) and i <len(typical_month_m[value]) and len(typical_month_m[value][i]):
50
+ typical_day_index['info'][key] = max(typical_month_m[value][i])
56
51
  for type_i in self.__type_list:
57
- if self.result['TypicalMonth'][m][type_i]:
58
- self.result['TypicalDay'][-1]['data'][type_i] = self.result['TypicalMonth'][m][type_i][i]
52
+ # 某月冷热负荷可能缺少后续典型日数据
53
+ if typical_month_m[type_i] and i < len(typical_month_m[type_i]):
54
+ typical_day_index['data'][type_i] = typical_month_m[type_i][i]
59
55
  self.__typicalIndex += 1
56
+ self.__plotIndex = length
60
57
 
61
58
  def GetTypical(self):
62
59
  '''
@@ -71,7 +68,7 @@ class IESLabTypicalDayResult(Result):
71
68
 
72
69
  def GetTypicalDayNum(self):
73
70
  '''
74
- 获取当前result的典型日数量
71
+ 获取当前result的典型日总数
75
72
 
76
73
  :return: int类型,代表典型日数量
77
74
  '''
@@ -82,25 +79,33 @@ class IESLabTypicalDayResult(Result):
82
79
  '''
83
80
  获取dayID对应典型日的基础信息
84
81
 
85
- :params: dayID int类型,表示典型日的ID,数值位于 0~典型日数量 之间
82
+ :params: dayID int类型,表示典型日的ID,数值位于 [0,典型日总数-1]
86
83
 
87
84
  :return: dict类型,代表典型日的基础信息,包括典型日所代表的日期范围、典型日的名称等
88
85
  '''
89
86
  self.__readPlotResult()
90
- return self.result['TypicalDay'][dayID].get('info','没有该数据')
87
+ try:
88
+ return self.result['TypicalDay'][dayID]['info']
89
+ except:
90
+ raise Exception('未查询到该数据')
91
91
 
92
92
 
93
93
  def GetTypicalDayCurve(self,dayID, dataType):
94
94
  '''
95
95
  获取dayID对应典型日下dataType参数的时序曲线
96
96
 
97
- :params: dayID int类型,表示典型日的ID,数值位于 0~典型日数量 之间
98
- :params: dataType enum类型,标识总辐射、环境温度、土壤温度、建筑物高度风速、风机高度风速、电负荷、热负荷、冷负荷的参数类型
97
+ :params: dayID int类型,表示典型日的ID,数值位于 [0,典型日总数-1]
98
+ :params: dataType enum类型,标识典型场景的数据类型
99
+ 有总辐射、直射辐照、散射辐照、环境温度、湿球温度、土壤温度、10m风速、50m风速、电负荷、热负荷、冷负荷和氢负荷等类型,以该典型场景实际包含的类型为准
99
100
 
100
101
  :return: list<float>类型,代表以1h为时间间隔的该参数的日内时序曲线
101
102
  '''
102
103
  self.__readPlotResult()
103
- return self.result['TypicalDay'][dayID]['data'].get(dataType,'没有该类型数据')
104
+ try:
105
+ return self.result['TypicalDay'][dayID]['data'][dataType]
106
+ except:
107
+ raise Exception('未查询到该数据')
108
+
104
109
 
105
110
 
106
111
  def GetTypicalMonth(self):
@@ -114,11 +119,11 @@ class IESLabTypicalDayResult(Result):
114
119
  self.__readPlotResult()
115
120
  return self.result['TypicalMonth']
116
121
 
117
- def GetTypicalMonthNum(self,monthID):
122
+ def GetTypicalMonthID(self,monthID):
118
123
  '''
119
124
  获取第monthID月各类型的典型日数据
120
125
 
121
- >>> result.GetTypicalMonthNum()
126
+ >>> result.GetTypicalMonthID()
122
127
 
123
128
  :params: monthID int类型,表示典型月的ID,数值位于 1-12 之间
124
129
 
@@ -126,17 +131,24 @@ class IESLabTypicalDayResult(Result):
126
131
  {...}
127
132
  '''
128
133
  self.__readPlotResult()
129
- return self.result['TypicalMonth'][monthID-1]
134
+ try:
135
+ return self.result['TypicalMonth'][monthID-1]
136
+ except:
137
+ raise Exception('未查询到该数据')
130
138
 
131
139
 
132
140
  def GetTypicalMonthCurve(self,monthID, dataType):
133
141
  '''
134
- 获取dayID对应典型日下dataType参数的时序曲线
142
+ 获取monthID对应典型日下dataType参数的时序曲线
135
143
 
136
144
  :params: monthID int类型,表示典型月的ID,数值位于 1-12 之间
137
- :params: dataType enum类型,标识总辐射、环境温度、土壤温度、建筑物高度风速、风机高度风速、电负荷、热负荷、冷负荷的参数类型
145
+ :params: dataType enum类型,标识典型场景的数据类型
146
+ 有总辐射、直射辐照、散射辐照、环境温度、湿球温度、土壤温度、10m风速、50m风速、电负荷、热负荷、冷负荷和氢负荷等类型,以该典型场景实际包含的类型为准
138
147
 
139
148
  :return: list<list>类型,代表以1h为时间间隔的该参数的典型日内时序曲线
140
149
  '''
141
150
  self.__readPlotResult()
142
- return self.result['TypicalMonth'][monthID-1].get(dataType,'没有该类型数据')
151
+ try:
152
+ return self.result['TypicalMonth'][monthID-1][dataType]
153
+ except:
154
+ raise Exception('未查询到该数据')
@@ -19,7 +19,7 @@ class Message(object):
19
19
  class MessageStreamReceiver(object):
20
20
  """消息流读取函数结果"""
21
21
 
22
- def __init__(self, id, db):
22
+ def __init__(self, id, db, **kwargs):
23
23
  self.origin = os.environ.get('CLOUDPSS_API_URL',
24
24
  'https://cloudpss.net/')
25
25
  self.id = id
@@ -28,102 +28,6 @@ class MessageStreamReceiver(object):
28
28
  self.error = None
29
29
  self.isOpen = False
30
30
 
31
- def create(self, type, comment=None, durability=1):
32
- """
33
- 创建消息流
34
- type: 消息流类型 'object' or 'binary'
35
- comment: 消息流描述
36
- durability: 消息流的数据将在多少天后被删除,其取值范围从 0 ~ MAX_DURABILITY
37
- MAX_DURABILITY 默认为20
38
- """
39
- param = {}
40
- if type != 'object' and type != 'binary':
41
- raise Exception('type must be object or binary')
42
- param['type'] = type
43
- param['comment'] = comment
44
- param['durability'] = durability
45
- r = requests.post(self.origin + 'api/streams', json=param)
46
- r.raise_for_status()
47
- res = r.json()
48
- print(res)
49
- message = Message(res['id'], res['token'])
50
- return message
51
-
52
- def createBulk(self, param):
53
- """
54
- 批量创建消息流
55
- param: [{ "type": "{{type}}", "comment": "{{comment}}" , "durability": {{durability}}, "volume": {{volume}} }, ... ]
56
- type: 消息流类型 'object' or 'binary'
57
- comment: 消息流描述
58
- durability: 消息流的数据将在多少天后被删除,其取值范围从 0 ~ MAX_DURABILITY
59
- MAX_DURABILITY 默认为20
60
-
61
- 状态码说明:
62
- 201 返回流信息数组
63
- 400 不支持的 type,或其他输入错误
64
- """
65
- r = requests.post(self.origin + 'api/streams/bulk', json=param)
66
- r.raise_for_status()
67
- res = r.json()
68
- messages = []
69
- for item in res:
70
- message = Message(item['id'], item['token'])
71
- messages.append(message)
72
- return messages
73
-
74
- def info(self, id):
75
- """
76
- 获取消息流信息
77
- """
78
- if id is None:
79
- raise Exception('id is None')
80
- r = requests.get(self.origin + 'api/streams/id/' + id + '/info')
81
- r.raise_for_status()
82
- return r.json()
83
-
84
- def infoByToken(self, token):
85
- """
86
- 获取消息流信息
87
- 相较于id获取消息流信息,token能够额外获取到handler的信息
88
- """
89
- if token is None:
90
- raise Exception('token is None')
91
- r = requests.get(self.origin + 'api/streams/token/' + token + '/info')
92
- r.raise_for_status()
93
- return r.json()
94
-
95
- def freeze(self, token):
96
- """
97
- 冻结消息流
98
-
99
- 状态码说明:
100
- 201 冻结成功
101
- 204 流已经被冻结
102
- 409 流正在活动中
103
- 404 未找到对应流
104
- """
105
- if token is None:
106
- raise Exception('token is None')
107
- r = requests.put(self.origin + 'api/streams/token/' + token +
108
- '/freeze')
109
- r.raise_for_status()
110
- return r.status_code
111
-
112
- def delete(self, token):
113
- """
114
- 删除消息流
115
-
116
- 状态码说明:
117
- 204 删除成功
118
- 409 流正在活动中
119
- 404 未找到对应流
120
- """
121
- if token is None:
122
- raise Exception('token is None')
123
- r = requests.delete(self.origin + 'api/streams/token/' + token)
124
- r.raise_for_status()
125
- return r.status_code
126
-
127
31
  def receive(self, id, fr0m, on_open, on_message, on_error, on_close):
128
32
  """
129
33
  读取消息流中的数据
@@ -142,13 +46,13 @@ class MessageStreamReceiver(object):
142
46
  path = head + '://' + str(u[1]) + '/api/streams/id/' + id
143
47
  if fr0m is not None:
144
48
  path = path + '&from=' + str(fr0m)
145
- ws = websocket.WebSocketApp(path,
49
+ self.ws = websocket.WebSocketApp(path,
146
50
  on_open=on_open,
147
51
  on_message=on_message,
148
52
  on_error=on_error,
149
53
  on_close=on_close)
150
- ws.run_forever()
151
- return ws
54
+ self.ws.run_forever()
55
+ return self.ws
152
56
 
153
57
  ###下面是兼容Receiver部分功能实现
154
58
  def on_message(self, ws, message):
@@ -182,6 +86,7 @@ class MessageStreamReceiver(object):
182
86
 
183
87
  def close(self, ws):
184
88
  ws.close()
89
+ self._status = 1
185
90
 
186
91
  def status(self):
187
92
  return self._status
cloudpss/runner/result.py CHANGED
@@ -84,8 +84,13 @@ class Result(object):
84
84
  def __deepModify(self, dict1, dict2):
85
85
 
86
86
  for key, val in dict1.items():
87
+
88
+
87
89
  if type(val) is dict:
88
- self.__deepModify(val, dict2[key])
90
+ if type(dict2) is dict and dict2.get(key, None) is None:
91
+ dict2[key] = val
92
+ else:
93
+ self.__deepModify(val, dict2[key])
89
94
  else:
90
95
  dict2[key] = val
91
96
 
cloudpss/runner/runner.py CHANGED
@@ -10,13 +10,12 @@ from cloudpss.utils.graphqlUtil import graphql_request
10
10
  from .receiver import Receiver
11
11
  from .MessageStreamReceiver import MessageStreamReceiver
12
12
  from .result import IESLabSimulationResult, PowerFlowResult, EMTResult, Result, IESResult
13
- from .IESLabPlanResult import IESLabPlanResult
14
- from .IESLabEvaluationResult import IESLabEvaluationResult
13
+ from .IESLabPlanResult import IESLabPlanResult, IESLabOptResult
14
+ from .IESLabEvaluationResult import IESLabEvaluationResult, IESLabPlanEvaluationResult, IESLabOptEvaluationResult
15
15
  from .IESLabTypicalDayResult import IESLabTypicalDayResult
16
16
  from .storage import Storage
17
17
  from ..utils import request
18
18
  from typing import TypeVar, Generic
19
- from .DSLabResult import DSLabResult
20
19
  import re
21
20
 
22
21
  RECEIVER = {
@@ -28,13 +27,16 @@ T = TypeVar('T', Result, EMTResult, PowerFlowResult, IESResult,
28
27
 
29
28
  IES_LAB_RESULT = {
30
29
  'function/ieslab/plan': IESLabPlanResult,
31
- 'function/ieslab/evaluation': IESLabEvaluationResult
30
+ 'function/ieslab/evaluation': IESLabPlanEvaluationResult,
32
31
  }
33
32
 
34
- DS_LAB_RESULT = {
35
- 'function/ieslab/evaluation': DSLabResult
33
+ IES_LAB_OPT_RESULT = {
34
+ 'function/ieslab/plan': IESLabOptResult,
35
+ 'function/ieslab/evaluation': IESLabOptEvaluationResult,
36
36
  }
37
37
 
38
+
39
+
38
40
  RESULT_DB = {
39
41
  'function/CloudPSS/emtp': EMTResult,
40
42
  'function/CloudPSS/emtps': EMTResult,
@@ -48,19 +50,23 @@ RESULT_DB = {
48
50
  'function/ies/ies-gmm':IESLabTypicalDayResult,
49
51
  'function/CloudPSS/ieslab-simulation': IESLabSimulationResult,
50
52
  'function/CloudPSS/ieslab-gmm':IESLabTypicalDayResult,
53
+ 'function/CloudPSS/ieslab-gmm-opt':IESLabTypicalDayResult,
51
54
  'function/CloudPSS/ieslab-optimization': IESResult,
52
55
  }
53
56
 
54
57
  @deprecated(version='4.0', reason="该类将在 6.0 版本移除,请使用 Job 类代替")
55
58
  class Runner(Generic[T]):
56
-
57
59
  def __init__(self, id,taskId, name, job, config, revision, modelRid, policy,
58
60
  **kwargs):
59
61
  self.id = id
60
62
  self.taskId = taskId
61
63
  self.db = Storage(taskId, name, job, config, revision, modelRid)
62
64
  rid =job['rid'].replace('job-definition/','function/').replace('/cloudpss/','/CloudPSS/')
63
- result = RESULT_DB.get(rid, Result)
65
+ resultClass = kwargs.get('RESULT_DB', None)
66
+ if resultClass is not None:
67
+ result = resultClass
68
+ else:
69
+ result = RESULT_DB.get(rid, Result)
64
70
  self.result: T = result(self.db)
65
71
  self.receiver = kwargs.get('receiver', None)
66
72
 
@@ -81,21 +87,29 @@ class Runner(Generic[T]):
81
87
  """
82
88
  if self.receiver is None:
83
89
  raise Exception('not find receiver')
90
+ time.sleep(0)
84
91
  return self.receiver.status()
85
92
 
86
93
  def __listen(self, **kwargs):
87
-
88
94
  receiver = kwargs.get('RECEIVER', 'default')
89
- receiverclass = None
90
95
  if type(receiver) is str:
91
96
  if receiver not in RECEIVER:
92
- receiverclass = RECEIVER['default']
97
+ receiver = RECEIVER['default']
93
98
  else:
94
- receiverclass = RECEIVER[receiver]
95
- if receiverclass is None:
99
+ receiver = RECEIVER[receiver]
100
+ if receiver is None:
96
101
  raise Exception('not find receiver')
97
- self.receiver = receiverclass(self.taskId, self.db, **kwargs)
102
+ self.receiver = receiver(self.taskId, self.db, **kwargs)
98
103
  self.receiver.connect()
104
+ def statusCode(self):
105
+ query="mutation($_a:JobInput!){job(input:$_a){status}}"
106
+ variables= {
107
+ "_a": {
108
+ "id": self.jobId,
109
+ }
110
+ }
111
+
112
+ return graphql_request(query,variables=variables)
99
113
 
100
114
  def terminate(self):
101
115
  """
@@ -103,7 +117,6 @@ class Runner(Generic[T]):
103
117
 
104
118
  """
105
119
  self.abort(0)
106
-
107
120
  def abort(self,timeout=3):
108
121
  """
109
122
  结束当前运行的算例
@@ -125,6 +138,57 @@ class Runner(Generic[T]):
125
138
  graphql_request(query, variables)
126
139
 
127
140
 
141
+ @staticmethod
142
+ def __createJobVariables(job, config, revisionHash, rid, policy, **kwargs):
143
+ # 处理policy字段
144
+ if policy is None:
145
+ policy = {}
146
+ if policy.get("tres", None) is None:
147
+ policy["tres"] = {}
148
+ policy["queue"] = job["args"].get("@queue", 1)
149
+ policy["priority"] = job["args"].get("@priority", 0)
150
+ tres = {"cpu": 1, "ecpu": 0, "mem": 0}
151
+ tresStr = job["args"].get("@tres", "")
152
+ for t in re.split("\s+", tresStr):
153
+ if t == "":
154
+ continue
155
+ k, v = t.split("=")
156
+ tres[k] = float(v) # type: ignore
157
+ policy["tres"] = tres
158
+ function = job["rid"].replace("job-definition/cloudpss/", "function/CloudPSS/")
159
+ implement = kwargs.get("implement", kwargs.get("topology", None))
160
+ debug = job["args"].get("@debug", None )
161
+ debugargs={}
162
+ if debug is not None:
163
+ t= [ i.split('=') for i in re.split(r'\s+',debug) if i.find('=')>0]
164
+ for i in t:
165
+ debugargs[i[0]]=i[1]
166
+
167
+ context= [
168
+ function,
169
+
170
+ f"model/@sdk/{str(int(time.time() * random.random()))}",
171
+ ]
172
+ if rid != '':
173
+ context.append(rid)
174
+
175
+ PARENT_JOB_ID =kwargs.get("PARENT_JOB_ID",None)
176
+ if PARENT_JOB_ID is not None:
177
+ context.append(f"job/parent/{PARENT_JOB_ID}")
178
+ variables = {
179
+ "input": {
180
+ "args": {
181
+ **job["args"],
182
+ "_ModelRevision": revisionHash,
183
+ "_ModelArgs": config["args"],
184
+ "implement":implement
185
+ },
186
+ "context": context,
187
+ "policy": policy,
188
+ "debug":debugargs
189
+ }
190
+ }
191
+ return variables
128
192
  @staticmethod
129
193
  def create(revisionHash,
130
194
  job,
@@ -147,41 +211,9 @@ class Runner(Generic[T]):
147
211
  >>> runner = Runner.runRevision(revision,job,config,'')
148
212
  '''
149
213
 
150
- #处理policy字段
151
- if policy is None:
152
- policy = {}
153
- if policy.get('tres', None) is None:
154
- policy['tres'] = {}
155
- policy['queue'] = job['args'].get('@queue', 1)
156
- policy['priority'] = job['args'].get('@priority', 0)
157
- tres = {'cpu': 1, 'ecpu': 0, 'mem': 0}
158
- tresStr = job['args'].get('@tres', '')
159
- for t in re.split('\s+', tresStr):
160
- if t == '':
161
- continue
162
- k, v = t.split('=')
163
- tres[k] = float(v) #type: ignore
164
- policy['tres'] = tres
165
214
 
166
215
  query = '''mutation($input:CreateJobInput!){job:createJob(input:$input){id input output status position}}'''
167
- function = job['rid'].replace('job-definition/cloudpss/',
168
- 'function/CloudPSS/')
169
- variables = {
170
- 'input': {
171
- "args":
172
- {
173
- **job['args'],
174
- '_ModelRevision' : revisionHash,
175
- '_ModelArgs' : config['args']
176
- },
177
- "context": [
178
- function,
179
- f"model/@sdk/{str(int(time.time() * random.random()))}"
180
- ],
181
- "policy":
182
- policy,
183
- }
184
- }
216
+ variables = Runner.__createJobVariables(job, config, revisionHash, rid,policy, **kwargs)
185
217
  r = graphql_request(query, variables)
186
218
  if 'errors' in r:
187
219
  raise Exception(r['errors'])
@@ -224,13 +256,25 @@ class HttpRunner(Runner[T]):
224
256
  return False
225
257
  return self.result.status() # type: ignore
226
258
 
227
- class DSLabRunner(Runner[T]):
259
+
260
+ class HttpOPTRunner(Runner[T]):
261
+
228
262
  def __init__(self, job, simulationId, **kwargs):
229
263
  self.simulationId = simulationId
230
264
  self.job = job
231
- result = DS_LAB_RESULT.get(job.get('rid', ''), DSLabResult)
232
- self.result: T = result(self.simulationId, **kwargs)
265
+ self.__taskId = self.__getLastTask()
266
+ result = IES_LAB_OPT_RESULT.get(job.get('rid', ''), IESLabOptResult)
267
+ self.result: T = result(self.simulationId, self.__taskId,
268
+ **kwargs) # type: ignore
233
269
 
234
- def status(self):
235
- return self.result.status()
270
+ def __getLastTask(self):
271
+ r = request('GET',
272
+ 'api/ieslab-opt/taskmanager/getSimuLastTasks',
273
+ params={'simuid': self.simulationId})
274
+ result = json.loads(r.text)
275
+ return result['data'].get('task_id', None)
236
276
 
277
+ def status(self):
278
+ if self.__taskId is None:
279
+ return False
280
+ return self.result.status() # type: ignore
cloudpss/utils/IO.py CHANGED
@@ -2,6 +2,7 @@ import io
2
2
  import json
3
3
  import ubjson
4
4
  import yaml
5
+ from yaml.dumper import SafeDumper
5
6
  import gzip
6
7
  import base64
7
8
  import struct
@@ -85,6 +86,7 @@ class IO(object):
85
86
  result = ubjson.dumpb(obj)
86
87
  if format == 'yaml':
87
88
  result = yaml.dump(obj).encode(encoding="utf-8")
89
+
88
90
  if result is None:
89
91
  assert False, 'format not support'
90
92
  if compress == 'gzip':
@@ -104,7 +106,7 @@ class IO(object):
104
106
  if format == 'ubjson':
105
107
  return ubjson.loadb(byt)
106
108
  if format == 'yaml':
107
- return yaml.load(io.BytesIO(byt), yaml.FullLoader)
109
+ return yaml.load(io.BytesIO(byt), Loader=yaml.FullLoader)
108
110
  assert False, 'format not support'
109
111
 
110
112
  @staticmethod
@@ -3,8 +3,9 @@ import json
3
3
  from cloudpss.utils import request
4
4
 
5
5
 
6
- def graphql_request(query, variables=None):
6
+ def graphql_request(query, variables=None, **kwargs):
7
7
  payload = {'query': query, 'variables': variables}
8
- r = request('POST', 'graphql', data=json.dumps(payload))
8
+
9
+ r = request('POST', 'graphql', data=json.dumps(payload), **kwargs)
9
10
 
10
11
  return json.loads(r.text)