cloudpss 4.5.1__py3-none-any.whl → 4.5.1a2__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.
@@ -0,0 +1,27 @@
1
+ from .curveData import 基准出力曲线, 基准出力曲线2, 基准出力曲线3, 负荷曲线, 策略曲线, 运行策略曲线
2
+
3
+ extra_paths = {
4
+ '光伏': 基准出力曲线,
5
+ '光伏曲线': 基准出力曲线,
6
+ '风机': 基准出力曲线,
7
+ '风机曲线': 基准出力曲线,
8
+ '燃气': 基准出力曲线2,
9
+ '燃气曲线': 基准出力曲线,
10
+ '水电': 基准出力曲线2,
11
+ '水电曲线': 基准出力曲线,
12
+ '火电': 基准出力曲线2,
13
+ '火电曲线': 基准出力曲线,
14
+ '生物质发电': 基准出力曲线2,
15
+ '生物质发电曲线': 基准出力曲线,
16
+ '垃圾电厂': 基准出力曲线2,
17
+ '垃圾电厂曲线': 基准出力曲线,
18
+ '负荷分类': 负荷曲线,
19
+ '负荷用户': 负荷曲线,
20
+ '储能运行策略': 运行策略曲线,
21
+ }
22
+
23
+ def getCurveData(kind):
24
+ if kind in extra_paths:
25
+ return extra_paths[kind]
26
+ else :
27
+ return []
@@ -0,0 +1,137 @@
1
+ import time
2
+ from cloudpss.runner.runner import Runner, HttpRunner, DSLabRunner
3
+ from cloudpss.runner.DSLabResult import DSLabResult
4
+ from ..utils import request
5
+ import json
6
+
7
+ class DSLabFinancialAnalysisModel(object):
8
+ _baseUri = 'api/dslab/rest/pe/'
9
+
10
+ _kindNameMap = {
11
+ "投资组成": "investmentbanchandproportion",
12
+ "资金来源": "capitalsource",
13
+ "资产形式": "assetformation",
14
+ "生产成本": "productioncost",
15
+ "流动资金及财务费用": "workingcapitalandfinancialexpenses",
16
+ "税率及附加": "projectcalculation",
17
+ }
18
+
19
+ # 财务评价基础参数接口默认值
20
+ _financialParasDefaultValues = {
21
+ "资产形式": {
22
+ "fixedAssetsRatio": "95",
23
+ "residualRrate": "5",
24
+ "depreciationPeriod": "15",
25
+ "reimbursementPeriod": "5"
26
+ },
27
+ "生产成本": {
28
+ 'annualSalary': "8",
29
+ 'capacity': "4",
30
+ 'insuranceRate': "0.25",
31
+ 'materialsExpenses': "5.0",
32
+ 'otherExpenses': "1.0",
33
+ 'welfareFactor': "0"
34
+ },
35
+ "流动资金及财务费用": {
36
+ "annualAPCirculationTimes": "12",
37
+ "annualARCirculationTimes": "12",
38
+ "annualCashCirculationTimes": "12",
39
+ "annualStockCirculationTimes": "12",
40
+ "interestRateAndWorkingCapital": "4",
41
+ "workingCapitalLoanRatio": "70"
42
+ },
43
+ "税率及附加": {
44
+ "aleatoricAccumulationFundRate": "0",
45
+ "basicDiscountRate": "8",
46
+ "cityMaintenanceConstructionTaxTate": "5",
47
+ "corporateIncomeTaxRate": "25",
48
+ "educationFeePlus": "5",
49
+ "electricityVATRate": "18",
50
+ "fuelBoughtVATRate": "10",
51
+ "hotColdVATRate": "12",
52
+ "legalAccumulationFundRate": "10",
53
+ "localEducationPlus": "2",
54
+ "materialBoughtVATRate": "17",
55
+ "steamSaleVATRate": "12"
56
+ }
57
+ }
58
+
59
+ def __init__(self, simulationId):
60
+ '''
61
+ 初始化
62
+ '''
63
+ self.simulationId = simulationId
64
+
65
+ def _saveItemData(self, url, data):
66
+ '''
67
+ 保存url链接对应的优化方案下财务评估模块的基础信息
68
+ :param url string类型,表示优化方案的接口链接
69
+
70
+ :return: dict 类型,代表方案对应的财务评价基础参数信息
71
+ '''
72
+ r = request('POST', url, None, data=json.dumps(data))
73
+ return json.loads(r.text)
74
+
75
+ def _fetchItemData(self, url, planID):
76
+ '''
77
+ 获取planID对应的优化方案下财务评估模块的基础信息
78
+ :param planID int类型,表示优化方案的ID,数值位于0~优化方案数量之间
79
+
80
+ :return: dict 类型,为源数据的引用,代表方案对应的财务评价基础参数信息
81
+ '''
82
+ r = request('GET',
83
+ url,
84
+ params={
85
+ "planId": planID,
86
+ "simu": self.simulationId
87
+ })
88
+ return json.loads(r.text)
89
+
90
+ def run(self, planID) -> Runner[DSLabResult]:
91
+ '''
92
+ 运行财务评价概览计算
93
+
94
+ :param planID int类型,表示优化方案的ID,数值位于0~优化方案数量之间
95
+
96
+ :return: Runner[DSLabResult]
97
+ '''
98
+ url = 'api/dslab/rest/saveDataToclickhouse'
99
+ try:
100
+ r = request('GET',
101
+ url,
102
+ params={
103
+ "planId": planID,
104
+ "simu": self.simulationId,
105
+ "CMD_TYPE": 'financialEvaluation'
106
+ })
107
+ data = json.loads(r.text)
108
+ return DSLabRunner({'rid': 'function/ieslab/evaluation'},
109
+ self.simulationId,
110
+ planId=planID,
111
+ cmdType='financialEvaluation')
112
+ except:
113
+ raise Exception('财务评价概览计算失败')
114
+
115
+ def GetFinancialParams(self, planID):
116
+ '''
117
+ 获取planID对应的优化方案下财务评估模块的基础信息
118
+ :param planID int类型,表示优化方案的ID,数值位于0~优化方案数量之间
119
+
120
+ :return: dict 类型,为源数据的引用,代表方案对应的财务评价基础参数信息
121
+ '''
122
+ dict_result = dict()
123
+ for k, v in self._kindNameMap.items():
124
+ kind = self._kindNameMap.get(k, k)
125
+ url = f"{self._baseUri}{kind}"
126
+ list_data = self._fetchItemData(url, planID)
127
+ if not list_data :
128
+ data = {
129
+ "simu": self.simulationId,
130
+ "planId": planID,
131
+ }
132
+ if k in self._financialParasDefaultValues:
133
+ data.update(self._financialParasDefaultValues[k])
134
+ dict_result[v] = self._saveItemData(url, data)
135
+ else:
136
+ dict_result[v] = list_data
137
+ return dict_result
@@ -0,0 +1,273 @@
1
+ import json
2
+ from collections import namedtuple
3
+ from typing import Any, Dict, List, Union
4
+
5
+ PARSER_STATUS_TEXT = 0
6
+ PARSER_STATUS_EXPRESSION_SIMPLE = 1
7
+ PARSER_STATUS_EXPRESSION_COMPLEX = 2
8
+
9
+ def is_identifier_char(char):
10
+ char_code = ord(char)
11
+ return ((char_code >= 97 and char_code <= 122) or
12
+ (char_code >= 65 and char_code <= 90) or
13
+ (char_code >= 48 and char_code <= 57) or
14
+ char_code == 95)
15
+
16
+ INTERPOLATION_CHAR = '$'
17
+ INTERPOLATION_EXPRESSION_START = '{'
18
+ INTERPOLATION_EXPRESSION_END = '}'
19
+
20
+ def parse_interpolation_impl(template, start, length):
21
+ templates = []
22
+ values = []
23
+ current_template = ''
24
+ current_value = ''
25
+ expression_complex_depth = 0
26
+ status = PARSER_STATUS_TEXT
27
+ end = start + length - 1
28
+
29
+ i = start
30
+ while i <= end:
31
+ if status == PARSER_STATUS_TEXT:
32
+ next_interpolation_char = template.find(INTERPOLATION_CHAR, i)
33
+ if next_interpolation_char < 0 or next_interpolation_char >= end:
34
+ current_template += template[i:end + 1]
35
+ break
36
+ current_template += template[i:next_interpolation_char]
37
+ next_char = template[next_interpolation_char + 1]
38
+ i = next_interpolation_char
39
+ if next_char == INTERPOLATION_CHAR:
40
+ current_template += INTERPOLATION_CHAR
41
+ i += 1
42
+ continue
43
+ if next_char == INTERPOLATION_EXPRESSION_START:
44
+ templates.append(current_template)
45
+ current_template = ''
46
+ status = PARSER_STATUS_EXPRESSION_COMPLEX
47
+ expression_complex_depth = 1
48
+ i += 1
49
+ continue
50
+ if is_identifier_char(next_char):
51
+ templates.append(current_template)
52
+ current_template = ''
53
+ current_value = next_char
54
+ status = PARSER_STATUS_EXPRESSION_SIMPLE
55
+ i += 1
56
+ continue
57
+ current_template += INTERPOLATION_CHAR
58
+ continue
59
+
60
+ char = template[i]
61
+ if status == PARSER_STATUS_EXPRESSION_SIMPLE:
62
+ if is_identifier_char(char):
63
+ current_value += char
64
+ i += 1
65
+ continue
66
+ values.append(current_value)
67
+ current_value = ''
68
+ status = PARSER_STATUS_TEXT
69
+ continue
70
+
71
+ if status == PARSER_STATUS_EXPRESSION_COMPLEX:
72
+ if char == INTERPOLATION_EXPRESSION_START:
73
+ expression_complex_depth += 1
74
+ elif char == INTERPOLATION_EXPRESSION_END:
75
+ expression_complex_depth -= 1
76
+ if expression_complex_depth == 0:
77
+ values.append(current_value.strip())
78
+ current_value = ''
79
+ status = PARSER_STATUS_TEXT
80
+ i += 1
81
+ continue
82
+ current_value += char
83
+ i += 1
84
+ continue
85
+
86
+ if status == PARSER_STATUS_TEXT:
87
+ templates.append(current_template)
88
+ elif status == PARSER_STATUS_EXPRESSION_SIMPLE:
89
+ values.append(current_value)
90
+ templates.append('')
91
+ else:
92
+ raise ValueError('Unexpected end of input')
93
+
94
+ return {
95
+ 'type': 'interpolation',
96
+ 'templates': templates,
97
+ 'values': values,
98
+ }
99
+
100
+ # 是否为 ArrayBuffer
101
+ def is_array_buffer(value: Any) -> bool:
102
+ return isinstance(value, (memoryview, bytearray))
103
+
104
+ # 是否为 Error
105
+ def is_error(value: Any) -> bool:
106
+ return isinstance(value, Exception)
107
+
108
+
109
+ def parse_template(template: str) -> Any:
110
+ if not template:
111
+ return ''
112
+ if template.startswith('='):
113
+ return {
114
+ 'type': 'formula',
115
+ 'value': template[1:].strip(),
116
+ }
117
+ if template.startswith('$'):
118
+ result = parse_interpolation_impl(template, 1, len(template)-1)
119
+ if len(result['templates']) == 0:
120
+ return result['templates'][0]
121
+ return result
122
+ return template
123
+ # KNOWN_ERRORS = [EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError]
124
+
125
+ # 模板序列号
126
+ seq = 0
127
+
128
+ # 创建模板
129
+ class TemplateCompiler:
130
+ def __init__(self, template: Any, options: Dict[str, Any]):
131
+ self.template = template
132
+ self.options = options
133
+ self.params = {}
134
+ self.copyable = []
135
+
136
+ # 构建求值
137
+ def build_eval(self, expression: str, type_: str) -> str:
138
+ evaluator = self.options['evaluator']
139
+ if 'evaluator' not in self.params:
140
+ self.params['evaluator'] = evaluator.get('inject',None)
141
+ return evaluator['compile'](expression, type_)
142
+
143
+ # 构建字符串
144
+ def build_string(self, str_: str) -> Union[str, bool]:
145
+ parsed = parse_template(str_)
146
+ if isinstance(parsed, str):
147
+ return json.dumps(parsed), False
148
+ if parsed['type'] == 'formula':
149
+ return self.build_eval(parsed['value'], parsed['type']), True
150
+ result = ''
151
+ for i in range(len(parsed['templates'])):
152
+ if parsed['templates'][i]:
153
+ result += (result and '+' or '') + json.dumps(parsed['templates'][i])
154
+ if i < len(parsed['values']):
155
+ if not result:
156
+ result = '""'
157
+ result += '+' + self.build_eval(parsed['values'][i], parsed['type'])
158
+ return result, True
159
+
160
+ # 构建 Error
161
+ def build_error(self, err: Exception) -> str:
162
+ constructor="Error"
163
+ if err.__class__.__name__ == constructor:
164
+ return f'new {constructor}({self.build_string(err.message)[0]})'
165
+ return f'Object.assign(new {constructor}({self.build_string(err.message)[0]}), {{name: {self.build_string(err.name)[0]}}})'
166
+
167
+ # 构建数组
168
+ def build_array(self, arr: List[Any]) -> str:
169
+ return f'[{", ".join(self.build_value(v) for v in arr)}]'
170
+
171
+ # 构建 ArrayBuffer
172
+ def build_array_buffer(self, buffer: Union[memoryview, bytearray]) -> str:
173
+ self.copyable.append(buffer[:])
174
+ return f'copyable[{len(self.copyable) - 1}][:]'
175
+
176
+ # 构建 ArrayBufferView
177
+ def build_array_buffer_view(self, view: memoryview) -> str:
178
+ self.copyable.append(view.tobytes())
179
+ return f'new {view.__class__.__name__}(copyable[{len(self.copyable) - 1}][:])'
180
+
181
+ # 构建对象
182
+ def build_object(self, obj: Dict[str, Any]) -> str:
183
+ result = ''
184
+ for key, value in obj.items():
185
+ if result:
186
+ result += ',\n'
187
+ if self.options['objectKeyMode'] == 'ignore':
188
+ result += json.dumps(key)
189
+ else:
190
+ e, is_expression = self.build_string(key)
191
+ if is_expression:
192
+ result += f'[{e}]'
193
+ else:
194
+ result += e
195
+ result += ':'
196
+ result += self.build_value(value)
197
+ return '{' + result + '}'
198
+
199
+ # 构建值
200
+ def build_value(self, value: Any) -> str:
201
+ if value is None:
202
+ return 'null'
203
+ if value is True:
204
+ return 'true'
205
+ if value is False:
206
+ return 'false'
207
+ if isinstance(value, (int, float)):
208
+ return str(value)
209
+ if isinstance(value, str):
210
+ return self.build_string(value)[0]
211
+ if isinstance(value, Exception):
212
+ return self.build_error(value)
213
+ if isinstance(value, list):
214
+ return self.build_array(value)
215
+ if is_array_buffer(value):
216
+ return self.build_array_buffer(value)
217
+ if isinstance(value, memoryview):
218
+ return self.build_array_buffer_view(value)
219
+ if isinstance(value, dict):
220
+ return self.build_object(value)
221
+ raise ValueError(f'Unsupported value: {type(value)}')
222
+
223
+ # 构建模板
224
+ def build(self) -> Any:
225
+ global seq
226
+ source = self.build_value(self.template)
227
+ if self.copyable:
228
+ self.params['copyable'] = self.copyable
229
+ params = list(self.params.items())
230
+ try:
231
+ result = eval(f'lambda context: ({source})')
232
+ result.source = source
233
+ return result
234
+ except Exception as e:
235
+ raise ValueError(f'Failed to compile template: {source}\n{str(e)}')
236
+
237
+
238
+
239
+ def template(templates,options={}):
240
+ def compile_template(expression, type):
241
+ if type == 'formula':
242
+ return f'context[{json.dumps(expression)}]'
243
+ elif type == 'interpolation':
244
+ return f"context[{json.dumps(expression)}] ?? ''"
245
+ raise ValueError(f'Unsupported type: {type}')
246
+ opt = {
247
+ 'objectKeyMode': 'template',
248
+ 'evaluator':{
249
+ 'compile':compile_template
250
+ },
251
+ **options
252
+ }
253
+ return TemplateCompiler(templates, opt).build()
254
+
255
+
256
+
257
+ if __name__ == "__main__":
258
+
259
+ message =[1, 1, {'component_load_5_无功功率': [0], 'component_load_5_有功功率': [0], 'time': ['placeholder']}, {'data': {'title': '负荷5功率(kW)', 'traces': [{'name': '有功功率', 'type': 'scatter', 'x': '=time', 'y': '=component_load_5_有功功率'}, {'name': '无功功率', 'type': 'scatter', 'x': '=time', 'y': '=component_load_5_无功功率'}], 'xAxis': {'title': 'time'}, 'yAxis': {'title': '功率(kW)'}}, 'key': '/component_load_5_功率(kW)', 'type': 'plot', 'verb': 'append', 'version': 1}]
260
+ id =message[0]
261
+
262
+ templates=message[3:]
263
+
264
+ x= template(templates)
265
+
266
+ values=[1, 1, {'component_load_5_无功功率': [5.44544554016478], 'component_load_5_有功功率': [16.3363363363363], 'time': ['2021-08-19 09:00:00']}]
267
+
268
+ print(x)
269
+
270
+ data= values[2]
271
+ s=x(data)
272
+
273
+ print(s)
@@ -0,0 +1,36 @@
1
+ from cloudpss.job.TemplateCompiler import template
2
+ class TemplateManager():
3
+
4
+ def __init__(self) -> None:
5
+ self.templateMap = {}
6
+
7
+ def isCreate(self, value):
8
+ return type(value) == list and len(value) > 3 and type(value[0]) == int and value[1] == 1
9
+
10
+ def create(self, value):
11
+ if not self.isCreate(value):
12
+ print("is create")
13
+ return
14
+ id =value[0]
15
+
16
+ templates=value[3:]
17
+ if self.templateMap.get(id,None) is not None:
18
+ logging.debug(f"template {id} is already exist")
19
+
20
+ self.templateMap[id] = {'template':template(templates),'value':value}
21
+
22
+
23
+
24
+ def isInvoke(self, value):
25
+ return type(value) == list and len(value) == 3 and type(value[0]) == int and value[1] == 1
26
+
27
+ def invoke(self, value):
28
+ if not self.isInvoke(value):
29
+ return []
30
+ id,_version,args = value
31
+
32
+ t = self.templateMap.get(id,None)
33
+ if t is None:
34
+ return []
35
+ return t['template'](args)
36
+
cloudpss/job/job.py CHANGED
@@ -202,7 +202,7 @@ class Job(Generic[T]):
202
202
  if receiver is not None:
203
203
  self.__receiver = receiver
204
204
  if self.__receiver is None:
205
- self.__receiver = MessageStreamReceiver(self)
205
+ self.__receiver = MessageStreamReceiver(self.output)
206
206
  self.__receiver.connect(**kwargs)
207
207
  return self.__receiver
208
208
 
@@ -216,7 +216,7 @@ class Job(Generic[T]):
216
216
  if sender is not None:
217
217
  self.__sender = sender
218
218
  if self.__sender is None:
219
- self.__sender = MessageStreamSender(self)
219
+ self.__sender = MessageStreamSender(self.input)
220
220
  self.__sender.connect_legacy(**kwargs)
221
221
  return self.__sender
222
222
 
@@ -1,5 +1,9 @@
1
+ import datetime
1
2
  import logging
2
3
  import sys
4
+
5
+ from cloudpss.job.TemplateManager import TemplateManager
6
+
3
7
  from .jobReceiver import JobReceiver
4
8
  import os
5
9
  from urllib.parse import urlparse
@@ -7,7 +11,6 @@ import websocket
7
11
  import pytz
8
12
  import threading
9
13
  import time
10
-
11
14
  utc_tz = pytz.timezone("UTC")
12
15
 
13
16
  from ..utils.IO import IO
@@ -18,15 +21,30 @@ class Message(object):
18
21
  self.id = id
19
22
  self.token = token
20
23
 
21
-
24
+
25
+
22
26
  class MessageStreamReceiver(JobReceiver):
23
- def __init__(self, job):
27
+ def __init__(self, output):
24
28
  super().__init__()
25
- self.job = job
26
- self.id =self.job.output
29
+ self.id = output
27
30
  self.origin = os.environ.get("CLOUDPSS_API_URL", "https://cloudpss.net/")
28
31
  self.__hasOpen = False
29
-
32
+ self.templates=TemplateManager()
33
+ self.timeOffset=0
34
+ self.lastMessageTime=0
35
+
36
+
37
+ def updateTime(self,timestamp):
38
+ self.lastMessageTime = timestamp
39
+
40
+ ## 判断是否到达当前时间点的数据或者消息流结束
41
+ def isEnd(self):
42
+
43
+ if self.status == 1:
44
+ return True
45
+ logging.debug('lastMessageTime',self.lastMessageTime)
46
+ return (self.lastMessageTime/1000)>=time.time()-self.timeOffset
47
+
30
48
  def __path(self, from_=None):
31
49
  if self.id is None:
32
50
  raise Exception("id is None")
@@ -39,21 +57,32 @@ class MessageStreamReceiver(JobReceiver):
39
57
 
40
58
  ###下面是兼容Receiver部分功能实现
41
59
  def __on_message_legacy(self, *args, **kwargs):
42
-
43
60
  if type(args[0]) != websocket.WebSocketApp:
44
61
  message = args[0]
45
62
  else:
46
63
  message = args[1]
47
64
  return self.__on_message(message)
48
-
49
65
  def __on_message(self, message):
50
66
 
51
67
  data = IO.deserialize(message, "ubjson")
68
+ self.updateTime(data["timestamp"])
52
69
  self.ws.url = self.__path(data["id"])
53
70
  msg = IO.deserialize(data["data"], "ubjson")
71
+
72
+ if type(msg) is list:
73
+ if len(msg) == 3:
74
+ pass
75
+
76
+ templateMessage = self.templates.invoke(msg)
77
+ # print(templateMessage)
78
+ for m in templateMessage:
79
+ self.messages.append(m)
80
+ return
81
+ else:
82
+ self.templates.create(msg)
83
+ return
84
+
54
85
  self.messages.append(msg)
55
- if(msg['type']=='terminate'):
56
- self.close(self.ws)
57
86
  return msg
58
87
 
59
88
 
@@ -101,6 +130,10 @@ class MessageStreamReceiver(JobReceiver):
101
130
 
102
131
  def __on_open(self,ws, *args, **kwargs):
103
132
  self.ws = ws
133
+ gmt_format = '%a, %d %b %Y %H:%M:%S GMT'
134
+ serverTime = datetime.datetime.strptime(ws.sock.headers['date'],gmt_format)
135
+ self.timeOffset = time.time()+time.timezone-serverTime.timestamp()
136
+
104
137
  logging.debug(f"MessageStreamReceiver on_open")
105
138
  self._status = 0
106
139
  self.__hasOpen = True
@@ -128,7 +161,7 @@ class MessageStreamReceiver(JobReceiver):
128
161
 
129
162
 
130
163
  def connect(self):
131
- self._status = 1
164
+ self._status = 0
132
165
  path = self.__path()
133
166
  logging.info(f"receive data from websocket: {path}")
134
167
  self.ws = websocket.WebSocketApp(
@@ -12,9 +12,9 @@ import logging
12
12
 
13
13
 
14
14
  class MessageStreamSender:
15
- def __init__(self, job):
15
+ def __init__(self, input):
16
16
  super().__init__()
17
- self.job = job
17
+ self.input = input
18
18
  self.origin = os.environ.get("CLOUDPSS_API_URL", "https://cloudpss.net/")
19
19
  self.__hasOpen = False
20
20
 
@@ -60,14 +60,14 @@ class MessageStreamSender:
60
60
  同步方法连接ws
61
61
  """
62
62
  self._status = 0
63
- if self.job.input is None:
63
+ if self.input is None:
64
64
  raise Exception("id is None")
65
- if self.job.input == "00000000-0000-0000-0000-000000000000":
65
+ if self.input == "00000000-0000-0000-0000-000000000000":
66
66
  return
67
67
  u = list(urlparse(self.origin))
68
68
  head = "wss" if u[0] == "https" else "ws"
69
69
 
70
- path = head + "://" + str(u[1]) + "/api/streams/token/" + self.job.input
70
+ path = head + "://" + str(u[1]) + "/api/streams/token/" + self.input
71
71
  logging.debug(f"MessageStreamSender data from websocket: {path}")
72
72
 
73
73
  self.ws = websocket.WebSocketApp(
@@ -82,7 +82,6 @@ class Result(object):
82
82
 
83
83
  >>> message= db.getMessagesByType('log')
84
84
  """
85
-
86
85
  result = []
87
86
  for val in self._receiver:
88
87
  if val['type'] == type: