cloudpss 4.0.0a7__py3-none-any.whl → 4.0.2__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.
- cloudpss/dslab/dataManageModel.py +13 -2
- cloudpss/dslab/dslab.py +65 -0
- cloudpss/job/__init__.py +5 -0
- cloudpss/job/job.py +277 -0
- cloudpss/job/jobMachine.py +11 -0
- cloudpss/job/jobPolicy.py +129 -0
- cloudpss/job/jobQueue.py +14 -0
- cloudpss/job/jobReceiver.py +33 -0
- cloudpss/job/jobTres.py +6 -0
- cloudpss/job/messageStreamReceiver.py +120 -0
- cloudpss/job/messageStreamSender.py +74 -0
- cloudpss/job/view/EMTView.py +216 -0
- cloudpss/job/view/IESLabSimulationView.py +5 -0
- cloudpss/job/view/IESLabTypicalDayView.py +27 -0
- cloudpss/job/view/IESView.py +103 -0
- cloudpss/job/view/PowerFlowView.py +80 -0
- cloudpss/job/view/__init__.py +42 -0
- cloudpss/job/view/view.py +122 -0
- cloudpss/utils/IO.py +18 -7
- cloudpss/utils/httprequests.py +1 -1
- cloudpss/version.py +1 -1
- {cloudpss-4.0.0a7.dist-info → cloudpss-4.0.2.dist-info}/METADATA +1 -1
- {cloudpss-4.0.0a7.dist-info → cloudpss-4.0.2.dist-info}/RECORD +25 -9
- {cloudpss-4.0.0a7.dist-info → cloudpss-4.0.2.dist-info}/WHEEL +0 -0
- {cloudpss-4.0.0a7.dist-info → cloudpss-4.0.2.dist-info}/top_level.txt +0 -0
@@ -182,16 +182,16 @@ class DataManageModel(object):
|
|
182
182
|
})
|
183
183
|
return json.loads(r.text)
|
184
184
|
|
185
|
-
def AddDataItem(self, kind, data):
|
185
|
+
def AddDataItem(self, kind, data, extra=None):
|
186
186
|
'''
|
187
187
|
向kind类型的数据库中添加内容为data的数据项
|
188
188
|
:params: kind str类型,数据的种类标识,包含:光伏、风机、燃气、水电、常规小火电、生物质发电、垃圾电厂、传输线、变压器、开关、负荷分类、负荷用户、储能配置、上网电价、输配电价、常数电价、阶梯电价、分时电价、分时阶梯电价
|
189
189
|
:params: data dict类型,表示添加的数据内容,其数据结构应满足对应数据项的结构要求
|
190
|
+
:params extra list类型,表示添加的基准出力曲线、负荷曲线、策略曲线数据
|
190
191
|
|
191
192
|
:return: list<dict>类型,返回该种类下所有数据项的列表
|
192
193
|
'''
|
193
194
|
assert (kind in self._kindUrlMap), "数据类型不存在"
|
194
|
-
extra = data.get('extra')
|
195
195
|
if extra is None or not extra:
|
196
196
|
extra = getCurveData(kind)
|
197
197
|
r = {
|
@@ -255,6 +255,17 @@ class DataManageModel(object):
|
|
255
255
|
assert (kind in self._kindUrlMap), "数据类型不存在"
|
256
256
|
url = f"{self._baseUri}rest/{kind}"
|
257
257
|
return self._fetchItemData(url)
|
258
|
+
|
259
|
+
def GetItemExtra(self, kind, uuid):
|
260
|
+
'''
|
261
|
+
获取kind类型对应数据项的基准出力曲线、负荷曲线、策略曲线数据
|
262
|
+
:params: kind str类型,数据的类型
|
263
|
+
:params: uuid str类型,数据的unique id
|
264
|
+
'''
|
265
|
+
assert (kind in self._kindUrlMap), "数据类型不存在"
|
266
|
+
url = f"{self._baseUri}rest/id/{uuid}"
|
267
|
+
data = self._fetchItemData(url)
|
268
|
+
return data.get('extra', None).get('data', None)
|
258
269
|
|
259
270
|
class DSLabDataManageModel(DataManageModel):
|
260
271
|
_baseUri = 'api/ies/'
|
cloudpss/dslab/dslab.py
CHANGED
@@ -143,3 +143,68 @@ class DSLab(object):
|
|
143
143
|
raise Exception("不是储能规划方案内核运行生成算法的计算方案")
|
144
144
|
return self.run(job=job, name=name)
|
145
145
|
|
146
|
+
@staticmethod
|
147
|
+
def createProjectGroup(name, description=None, createById=None):
|
148
|
+
'''
|
149
|
+
创建项目组
|
150
|
+
|
151
|
+
:params name: String 项目组名称
|
152
|
+
:params description: String 项目组描述 可选参数
|
153
|
+
:params createById Int 父项目组id 可选参数,如果是从已有项目组导入的项目组,必填此项
|
154
|
+
|
155
|
+
:return: Int 返回创建的项目组id
|
156
|
+
'''
|
157
|
+
try:
|
158
|
+
if createById is None:
|
159
|
+
isImport = 0
|
160
|
+
else:
|
161
|
+
isImport = 1
|
162
|
+
payload = {
|
163
|
+
'name': name,
|
164
|
+
'description': description,
|
165
|
+
'isImport': isImport,
|
166
|
+
'createById': createById,
|
167
|
+
}
|
168
|
+
r = request(
|
169
|
+
'POST', 'api/ies/rest/group', data=json.dumps(payload))
|
170
|
+
if r.ok:
|
171
|
+
r = request('GET', 'api/ies/rest/group')
|
172
|
+
groupList = json.loads(r.text)
|
173
|
+
id = groupList[len(groupList) -1].get('id', None)
|
174
|
+
return id
|
175
|
+
except Exception as e:
|
176
|
+
raise Exception('创建项目组失败')
|
177
|
+
|
178
|
+
@staticmethod
|
179
|
+
def createProject(name, gid, description=None, initialTerm=None, build=None, operate=None, yearsInOperation=None):
|
180
|
+
'''
|
181
|
+
创建项目
|
182
|
+
|
183
|
+
:params name: String 项目名称
|
184
|
+
:params gid: Int 父项目组id,
|
185
|
+
:params description: String 项目描述, 可选参数
|
186
|
+
:params initialTerm: String 项目起始年限,可选参数
|
187
|
+
:params build: String 项目建设期(年),可选参数
|
188
|
+
:params operate: String 项目生命周期(年),可选参数
|
189
|
+
:params yearsInOperation: String 已投运年限,可选参数
|
190
|
+
|
191
|
+
:return: Int 返回创建的项目id
|
192
|
+
'''
|
193
|
+
try:
|
194
|
+
payload = {
|
195
|
+
'name': name,
|
196
|
+
'gid': gid,
|
197
|
+
'description': description,
|
198
|
+
'config': {
|
199
|
+
'initialTerm': initialTerm,
|
200
|
+
'build': build,
|
201
|
+
'operate': operate,
|
202
|
+
'yearsInOperation': yearsInOperation,
|
203
|
+
}
|
204
|
+
}
|
205
|
+
r = request(
|
206
|
+
'POST', 'api/ies/rest/simulation', data=json.dumps(payload))
|
207
|
+
project = json.loads(r.text)
|
208
|
+
return project.get('resource', None)
|
209
|
+
except Exception as e:
|
210
|
+
raise Exception('创建项目失败')
|
cloudpss/job/__init__.py
ADDED
cloudpss/job/job.py
ADDED
@@ -0,0 +1,277 @@
|
|
1
|
+
import random
|
2
|
+
import re
|
3
|
+
import time
|
4
|
+
from .view import getViewClass
|
5
|
+
|
6
|
+
from cloudpss.utils.IO import IO
|
7
|
+
from .messageStreamReceiver import MessageStreamReceiver
|
8
|
+
|
9
|
+
from cloudpss.utils.graphqlUtil import graphql_request
|
10
|
+
from .jobPolicy import JobPolicy
|
11
|
+
from .jobMachine import JobMachine
|
12
|
+
from .messageStreamSender import MessageStreamSender
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
class Job(object):
|
17
|
+
"""docstring for Job"""
|
18
|
+
|
19
|
+
def __init__(self, id, args, createTime, startTime, endTime, status,
|
20
|
+
context, user, priority, policy, machine, input, output,
|
21
|
+
position):
|
22
|
+
super(Job, self).__init__()
|
23
|
+
self.id = id
|
24
|
+
self.args = args
|
25
|
+
self.createTime = createTime
|
26
|
+
self.startTime = startTime
|
27
|
+
self.endTime = endTime
|
28
|
+
self.status = status
|
29
|
+
self.context = context
|
30
|
+
self.user = user
|
31
|
+
self.priority = priority
|
32
|
+
self.policy = policy # type: ignore
|
33
|
+
self.machine = JobMachine(**machine) # type: ignore
|
34
|
+
self.input = input
|
35
|
+
self.output = output
|
36
|
+
self.position = position
|
37
|
+
self.__receiver = None
|
38
|
+
self.__sender = None
|
39
|
+
|
40
|
+
@staticmethod
|
41
|
+
def fetch(id):
|
42
|
+
"""
|
43
|
+
获取job信息
|
44
|
+
"""
|
45
|
+
if id is None:
|
46
|
+
raise Exception('id is None')
|
47
|
+
query = '''query($_a:JobInput!){
|
48
|
+
job(input:$_a){
|
49
|
+
id
|
50
|
+
args
|
51
|
+
createTime
|
52
|
+
startTime
|
53
|
+
endTime
|
54
|
+
status
|
55
|
+
context
|
56
|
+
user
|
57
|
+
priority
|
58
|
+
policy {
|
59
|
+
name
|
60
|
+
queue
|
61
|
+
tres {
|
62
|
+
cpu
|
63
|
+
ecpu
|
64
|
+
mem
|
65
|
+
}
|
66
|
+
priority
|
67
|
+
maxDuration
|
68
|
+
}
|
69
|
+
machine {
|
70
|
+
id
|
71
|
+
name
|
72
|
+
tres {
|
73
|
+
cpu
|
74
|
+
ecpu
|
75
|
+
mem
|
76
|
+
}
|
77
|
+
}
|
78
|
+
input
|
79
|
+
output
|
80
|
+
position
|
81
|
+
}
|
82
|
+
}'''
|
83
|
+
variables = {"_a": {"id": id}}
|
84
|
+
r = graphql_request(query, variables)
|
85
|
+
if 'errors' in r:
|
86
|
+
raise Exception(r['errors'])
|
87
|
+
return Job(**r['data']['job'])
|
88
|
+
|
89
|
+
@staticmethod
|
90
|
+
def fetchMany(input):
|
91
|
+
"""
|
92
|
+
批量获取任务信息
|
93
|
+
"""
|
94
|
+
if input is None:
|
95
|
+
raise Exception('input is None')
|
96
|
+
query = '''query($_a:JobsInput!){
|
97
|
+
jobs(input:$_a){
|
98
|
+
item {
|
99
|
+
id
|
100
|
+
args
|
101
|
+
createTime
|
102
|
+
startTime
|
103
|
+
endTime
|
104
|
+
status
|
105
|
+
context
|
106
|
+
user
|
107
|
+
priority
|
108
|
+
policy {
|
109
|
+
id
|
110
|
+
name
|
111
|
+
users
|
112
|
+
functions
|
113
|
+
tres {
|
114
|
+
cpu
|
115
|
+
ecpu
|
116
|
+
mem
|
117
|
+
}
|
118
|
+
minPriority
|
119
|
+
maxPriority
|
120
|
+
maxDuration
|
121
|
+
createTime
|
122
|
+
updateTime
|
123
|
+
visibility
|
124
|
+
queue
|
125
|
+
}
|
126
|
+
machine {
|
127
|
+
id
|
128
|
+
name
|
129
|
+
tres {
|
130
|
+
cpu
|
131
|
+
ecpu
|
132
|
+
mem
|
133
|
+
}
|
134
|
+
valid
|
135
|
+
}
|
136
|
+
input
|
137
|
+
output
|
138
|
+
position
|
139
|
+
}
|
140
|
+
cursor
|
141
|
+
count
|
142
|
+
total
|
143
|
+
}
|
144
|
+
}'''
|
145
|
+
variables = {"_a": input}
|
146
|
+
r = graphql_request(query, variables)
|
147
|
+
if 'errors' in r:
|
148
|
+
raise Exception(r['errors'])
|
149
|
+
jobs = []
|
150
|
+
for job in r['data']['jobs']['item']:
|
151
|
+
jobs.append(Job(**job))
|
152
|
+
return jobs
|
153
|
+
|
154
|
+
@staticmethod
|
155
|
+
def create(revisionHash,
|
156
|
+
job,
|
157
|
+
config,
|
158
|
+
name=None,
|
159
|
+
rid='',
|
160
|
+
policy=None,
|
161
|
+
**kwargs):
|
162
|
+
'''
|
163
|
+
创建一个运行任务
|
164
|
+
|
165
|
+
:params: revision 项目版本号
|
166
|
+
:params: job 调用仿真时使用的计算方案,为空时使用项目的第一个计算方案
|
167
|
+
:params: config 调用仿真时使用的参数方案,为空时使用项目的第一个参数方案
|
168
|
+
:params: name 任务名称,为空时使用项目的参数方案名称和计算方案名称
|
169
|
+
:params: rid 项目rid,可为空
|
170
|
+
|
171
|
+
:return: 返回一个运行实例
|
172
|
+
|
173
|
+
>>> runner = Runner.runRevision(revision,job,config,'')
|
174
|
+
'''
|
175
|
+
|
176
|
+
#处理policy字段
|
177
|
+
if policy is None:
|
178
|
+
policy = {}
|
179
|
+
if policy.get('tres', None) is None:
|
180
|
+
policy['tres'] = {}
|
181
|
+
policy['queue'] = job['args'].get('@queue', 1)
|
182
|
+
policy['priority'] = job['args'].get('@priority', 0)
|
183
|
+
tres = {'cpu': 1, 'ecpu': 0, 'mem': 0}
|
184
|
+
tresStr = job['args'].get('@tres', '')
|
185
|
+
for t in re.split('\s+', tresStr):
|
186
|
+
if t == '':
|
187
|
+
continue
|
188
|
+
k, v = t.split('=')
|
189
|
+
tres[k] = float(v) #type: ignore
|
190
|
+
policy['tres'] = tres
|
191
|
+
|
192
|
+
query = '''mutation($input:CreateJobInput!){job:createJob(input:$input){id input output status position}}'''
|
193
|
+
function = job['rid'].replace('job-definition/cloudpss/',
|
194
|
+
'function/CloudPSS/')
|
195
|
+
variables = {
|
196
|
+
'input': {
|
197
|
+
"args": {
|
198
|
+
**job['args'], '_ModelRevision': revisionHash,
|
199
|
+
'_ModelArgs': config['args']
|
200
|
+
},
|
201
|
+
"context": [
|
202
|
+
function,
|
203
|
+
rid,
|
204
|
+
f"model/@sdk/{str(int(time.time() * random.random()))}"
|
205
|
+
],
|
206
|
+
"policy":
|
207
|
+
policy,
|
208
|
+
}
|
209
|
+
}
|
210
|
+
r = graphql_request(query, variables)
|
211
|
+
if 'errors' in r:
|
212
|
+
raise Exception(r['errors'])
|
213
|
+
id = r['data']['job']['id']
|
214
|
+
return Job.fetch(id)
|
215
|
+
|
216
|
+
@staticmethod
|
217
|
+
def abort(id, timeout):
|
218
|
+
"""
|
219
|
+
结束当前运行的算例
|
220
|
+
|
221
|
+
"""
|
222
|
+
query = '''mutation ($input: AbortJobInput!) {
|
223
|
+
job: abortJob(input: $input) {
|
224
|
+
id
|
225
|
+
status
|
226
|
+
}
|
227
|
+
}
|
228
|
+
'''
|
229
|
+
variables = {'input': {'id': id, 'timeout': timeout}}
|
230
|
+
graphql_request(query, variables)
|
231
|
+
|
232
|
+
@staticmethod
|
233
|
+
def load(file, format='yaml'):
|
234
|
+
return IO.load(file, format)
|
235
|
+
|
236
|
+
@staticmethod
|
237
|
+
def dump(job, file, format='yaml', compress='gzip'):
|
238
|
+
return IO.dump(job, file, format, compress)
|
239
|
+
|
240
|
+
def read(self, receiver=None, dev=False, **kwargs):
|
241
|
+
"""
|
242
|
+
使用接收器获取当前运行实例的输出
|
243
|
+
"""
|
244
|
+
if receiver is not None:
|
245
|
+
self.__sender = receiver
|
246
|
+
if self.__receiver is None:
|
247
|
+
self.__receiver = MessageStreamReceiver(self, dev)
|
248
|
+
self.__receiver.connect(**kwargs)
|
249
|
+
return self.__receiver
|
250
|
+
|
251
|
+
def write(self,sender=None, dev=False, **kwargs)->MessageStreamSender:
|
252
|
+
"""
|
253
|
+
使用发送器为当前运行实例输入
|
254
|
+
"""
|
255
|
+
|
256
|
+
if sender is not None:
|
257
|
+
self.__sender = sender
|
258
|
+
if self.__sender is None:
|
259
|
+
self.__sender =MessageStreamSender(self,dev)
|
260
|
+
self.__sender.connect(**kwargs)
|
261
|
+
return self.__sender
|
262
|
+
|
263
|
+
@property
|
264
|
+
def result(self):
|
265
|
+
"""
|
266
|
+
获取当前运行实例的输出
|
267
|
+
"""
|
268
|
+
viewType = getViewClass(self.context[0])
|
269
|
+
return self.view(viewType)
|
270
|
+
|
271
|
+
def view(self, viewType):
|
272
|
+
"""
|
273
|
+
获取当前运行实例的输出
|
274
|
+
"""
|
275
|
+
receiver = self.read()
|
276
|
+
sender=self.write()
|
277
|
+
return viewType(receiver,sender)
|
@@ -0,0 +1,129 @@
|
|
1
|
+
from cloudpss.job.jobQueue import JobQueue
|
2
|
+
from cloudpss.job.jobTres import JobTres
|
3
|
+
from cloudpss.utils.graphqlUtil import graphql_request
|
4
|
+
|
5
|
+
|
6
|
+
class JobPolicy(object):
|
7
|
+
|
8
|
+
def __init__(self, id, name, users, functions, tres, minPriority,
|
9
|
+
maxPriority, maxDuration, createTime, updateTime, visibility,
|
10
|
+
queue):
|
11
|
+
self.id = id
|
12
|
+
self.name = name
|
13
|
+
self.users = users
|
14
|
+
self.functions = functions
|
15
|
+
print(tres)
|
16
|
+
self.tres = []
|
17
|
+
for tre in tres:
|
18
|
+
self.tres.append(JobTres(**tre)) # type: ignore
|
19
|
+
self.minPriority = minPriority
|
20
|
+
self.maxPriority = maxPriority
|
21
|
+
self.maxDuration = maxDuration
|
22
|
+
self.createTime = createTime
|
23
|
+
self.updateTime = updateTime
|
24
|
+
self.visibility = visibility
|
25
|
+
self.queue = JobQueue(**queue) # type: ignore
|
26
|
+
|
27
|
+
@staticmethod
|
28
|
+
def fetch(id):
|
29
|
+
query = '''query($input:JobPolicyInput!)
|
30
|
+
{
|
31
|
+
jobPolicy(input:$input)
|
32
|
+
{
|
33
|
+
id
|
34
|
+
name
|
35
|
+
users
|
36
|
+
functions
|
37
|
+
tres {
|
38
|
+
cpu
|
39
|
+
ecpu
|
40
|
+
mem
|
41
|
+
}
|
42
|
+
minPriority
|
43
|
+
maxPriority
|
44
|
+
maxDuration
|
45
|
+
createTime
|
46
|
+
updateTime
|
47
|
+
visibility
|
48
|
+
queue {
|
49
|
+
id
|
50
|
+
name
|
51
|
+
scheduler
|
52
|
+
machines {
|
53
|
+
id
|
54
|
+
name
|
55
|
+
tres {
|
56
|
+
cpu
|
57
|
+
ecpu
|
58
|
+
mem
|
59
|
+
}
|
60
|
+
valid
|
61
|
+
}
|
62
|
+
createTime
|
63
|
+
updateTime
|
64
|
+
load
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
}'''
|
69
|
+
variables = {'input': {'id': id}}
|
70
|
+
r = graphql_request(query, variables)
|
71
|
+
print (r)
|
72
|
+
if 'errors' in r:
|
73
|
+
raise Exception(r['errors'])
|
74
|
+
return JobPolicy(**r['data']['jobPolicy'])
|
75
|
+
|
76
|
+
@staticmethod
|
77
|
+
def fetchMany(input):
|
78
|
+
query = '''query($input:JobPoliciesInput!)
|
79
|
+
{
|
80
|
+
jobPolicies(input:$input)
|
81
|
+
{
|
82
|
+
items {
|
83
|
+
id
|
84
|
+
name
|
85
|
+
users
|
86
|
+
functions
|
87
|
+
tres {
|
88
|
+
cpu
|
89
|
+
ecpu
|
90
|
+
mem
|
91
|
+
}
|
92
|
+
minPriority
|
93
|
+
maxPriority
|
94
|
+
maxDuration
|
95
|
+
createTime
|
96
|
+
updateTime
|
97
|
+
visibility
|
98
|
+
queue {
|
99
|
+
id
|
100
|
+
name
|
101
|
+
scheduler
|
102
|
+
machines {
|
103
|
+
id
|
104
|
+
name
|
105
|
+
tres {
|
106
|
+
cpu
|
107
|
+
ecpu
|
108
|
+
mem
|
109
|
+
}
|
110
|
+
valid
|
111
|
+
}
|
112
|
+
createTime
|
113
|
+
updateTime
|
114
|
+
load
|
115
|
+
}
|
116
|
+
}
|
117
|
+
cursor
|
118
|
+
count
|
119
|
+
total
|
120
|
+
}
|
121
|
+
}'''
|
122
|
+
variables = {'input': input}
|
123
|
+
r = graphql_request(query, variables)
|
124
|
+
if 'errors' in r:
|
125
|
+
raise Exception(r['errors'])
|
126
|
+
policies = []
|
127
|
+
for policy in r['data']['jobPolicies']['items']:
|
128
|
+
policies.append(JobPolicy(**policy))
|
129
|
+
return policies
|
cloudpss/job/jobQueue.py
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
from cloudpss.job.jobMachine import JobMachine
|
2
|
+
|
3
|
+
|
4
|
+
class JobQueue(object):
|
5
|
+
|
6
|
+
def __init__(self, id, name, scheduler, machines, createTime, updateTime,
|
7
|
+
load):
|
8
|
+
self.id = id
|
9
|
+
self.name = name
|
10
|
+
self.scheduler = scheduler
|
11
|
+
self.machines = [JobMachine(**m) for m in machines]
|
12
|
+
self.createTime = createTime
|
13
|
+
self.updateTime = updateTime
|
14
|
+
self.load = load
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class JobReceiver(object):
|
2
|
+
messages = []
|
3
|
+
index = 0
|
4
|
+
|
5
|
+
def __init__(self):
|
6
|
+
self.index = 0
|
7
|
+
self.messages = []
|
8
|
+
|
9
|
+
def __len__(self):
|
10
|
+
return len(self.messages)
|
11
|
+
|
12
|
+
def __iter__(self):
|
13
|
+
return self
|
14
|
+
|
15
|
+
def __next__(self):
|
16
|
+
maxLength = len(self.messages)
|
17
|
+
if self.index < maxLength:
|
18
|
+
message = self.messages[self.index]
|
19
|
+
self.index += 1
|
20
|
+
return message
|
21
|
+
raise StopIteration()
|
22
|
+
|
23
|
+
def view(self, ViewType):
|
24
|
+
"""
|
25
|
+
获取指定类型的视图数据
|
26
|
+
|
27
|
+
:params viewType: 视图类型
|
28
|
+
|
29
|
+
:returns: 对应类型的视图数据
|
30
|
+
|
31
|
+
>>> view= receiver.view(EMTView)
|
32
|
+
"""
|
33
|
+
return ViewType(self)
|