PyAutomationIO 0.0.0__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.
- automation/__init__.py +46 -0
- automation/alarms/__init__.py +563 -0
- automation/alarms/states.py +192 -0
- automation/alarms/trigger.py +64 -0
- automation/buffer.py +132 -0
- automation/core.py +1775 -0
- automation/dbmodels/__init__.py +23 -0
- automation/dbmodels/alarms.py +524 -0
- automation/dbmodels/core.py +86 -0
- automation/dbmodels/events.py +153 -0
- automation/dbmodels/logs.py +155 -0
- automation/dbmodels/machines.py +181 -0
- automation/dbmodels/opcua.py +81 -0
- automation/dbmodels/opcua_server.py +174 -0
- automation/dbmodels/tags.py +921 -0
- automation/dbmodels/users.py +259 -0
- automation/extensions/__init__.py +15 -0
- automation/extensions/api.py +149 -0
- automation/extensions/cors.py +18 -0
- automation/filter/__init__.py +19 -0
- automation/iad/__init__.py +3 -0
- automation/iad/frozen_data.py +54 -0
- automation/iad/out_of_range.py +51 -0
- automation/iad/outliers.py +51 -0
- automation/logger/__init__.py +0 -0
- automation/logger/alarms.py +426 -0
- automation/logger/core.py +265 -0
- automation/logger/datalogger.py +646 -0
- automation/logger/events.py +194 -0
- automation/logger/logdict.py +53 -0
- automation/logger/logs.py +203 -0
- automation/logger/machines.py +248 -0
- automation/logger/opcua_server.py +130 -0
- automation/logger/users.py +96 -0
- automation/managers/__init__.py +4 -0
- automation/managers/alarms.py +455 -0
- automation/managers/db.py +328 -0
- automation/managers/opcua_client.py +186 -0
- automation/managers/state_machine.py +183 -0
- automation/models.py +174 -0
- automation/modules/__init__.py +14 -0
- automation/modules/alarms/__init__.py +0 -0
- automation/modules/alarms/resources/__init__.py +10 -0
- automation/modules/alarms/resources/alarms.py +280 -0
- automation/modules/alarms/resources/summary.py +79 -0
- automation/modules/events/__init__.py +0 -0
- automation/modules/events/resources/__init__.py +10 -0
- automation/modules/events/resources/events.py +83 -0
- automation/modules/events/resources/logs.py +109 -0
- automation/modules/tags/__init__.py +0 -0
- automation/modules/tags/resources/__init__.py +8 -0
- automation/modules/tags/resources/tags.py +201 -0
- automation/modules/users/__init__.py +2 -0
- automation/modules/users/resources/__init__.py +10 -0
- automation/modules/users/resources/models/__init__.py +2 -0
- automation/modules/users/resources/models/roles.py +5 -0
- automation/modules/users/resources/models/users.py +14 -0
- automation/modules/users/resources/roles.py +38 -0
- automation/modules/users/resources/users.py +113 -0
- automation/modules/users/roles.py +121 -0
- automation/modules/users/users.py +335 -0
- automation/opcua/__init__.py +1 -0
- automation/opcua/models.py +541 -0
- automation/opcua/subscription.py +259 -0
- automation/pages/__init__.py +0 -0
- automation/pages/alarms.py +34 -0
- automation/pages/alarms_history.py +21 -0
- automation/pages/assets/styles.css +7 -0
- automation/pages/callbacks/__init__.py +28 -0
- automation/pages/callbacks/alarms.py +218 -0
- automation/pages/callbacks/alarms_summary.py +20 -0
- automation/pages/callbacks/db.py +222 -0
- automation/pages/callbacks/filter.py +238 -0
- automation/pages/callbacks/machines.py +29 -0
- automation/pages/callbacks/machines_detailed.py +581 -0
- automation/pages/callbacks/opcua.py +266 -0
- automation/pages/callbacks/opcua_server.py +244 -0
- automation/pages/callbacks/tags.py +495 -0
- automation/pages/callbacks/trends.py +119 -0
- automation/pages/communications.py +129 -0
- automation/pages/components/__init__.py +123 -0
- automation/pages/components/alarms.py +151 -0
- automation/pages/components/alarms_summary.py +45 -0
- automation/pages/components/database.py +128 -0
- automation/pages/components/gaussian_filter.py +69 -0
- automation/pages/components/machines.py +396 -0
- automation/pages/components/opcua.py +384 -0
- automation/pages/components/opcua_server.py +53 -0
- automation/pages/components/tags.py +253 -0
- automation/pages/components/trends.py +66 -0
- automation/pages/database.py +26 -0
- automation/pages/filter.py +55 -0
- automation/pages/machines.py +20 -0
- automation/pages/machines_detailed.py +41 -0
- automation/pages/main.py +63 -0
- automation/pages/opcua_server.py +28 -0
- automation/pages/tags.py +40 -0
- automation/pages/trends.py +35 -0
- automation/singleton.py +30 -0
- automation/state_machine.py +1672 -0
- automation/tags/__init__.py +2 -0
- automation/tags/cvt.py +1198 -0
- automation/tags/filter.py +55 -0
- automation/tags/tag.py +418 -0
- automation/tests/__init__.py +10 -0
- automation/tests/test_alarms.py +110 -0
- automation/tests/test_core.py +257 -0
- automation/tests/test_unit.py +21 -0
- automation/tests/test_user.py +155 -0
- automation/utils/__init__.py +164 -0
- automation/utils/decorators.py +222 -0
- automation/utils/npw.py +294 -0
- automation/utils/observer.py +21 -0
- automation/utils/units.py +118 -0
- automation/variables/__init__.py +55 -0
- automation/variables/adimentional.py +30 -0
- automation/variables/current.py +71 -0
- automation/variables/density.py +115 -0
- automation/variables/eng_time.py +68 -0
- automation/variables/force.py +90 -0
- automation/variables/length.py +104 -0
- automation/variables/mass.py +80 -0
- automation/variables/mass_flow.py +101 -0
- automation/variables/percentage.py +30 -0
- automation/variables/power.py +113 -0
- automation/variables/pressure.py +93 -0
- automation/variables/temperature.py +168 -0
- automation/variables/volume.py +70 -0
- automation/variables/volumetric_flow.py +100 -0
- automation/workers/__init__.py +2 -0
- automation/workers/logger.py +164 -0
- automation/workers/state_machine.py +207 -0
- automation/workers/worker.py +36 -0
- pyautomationio-0.0.0.dist-info/METADATA +198 -0
- pyautomationio-0.0.0.dist-info/RECORD +138 -0
- pyautomationio-0.0.0.dist-info/WHEEL +5 -0
- pyautomationio-0.0.0.dist-info/licenses/LICENSE +21 -0
- pyautomationio-0.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""pyhades/logger/alarms.py
|
|
3
|
+
"""
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from ..dbmodels import Alarms, AlarmSummary, AlarmTypes, AlarmStates
|
|
6
|
+
from .core import BaseEngine, BaseLogger
|
|
7
|
+
from ..alarms.trigger import TriggerType
|
|
8
|
+
from ..alarms.states import AlarmState
|
|
9
|
+
from ..utils.decorators import db_rollback
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AlarmsLogger(BaseLogger):
|
|
13
|
+
|
|
14
|
+
def __init__(self):
|
|
15
|
+
|
|
16
|
+
super(AlarmsLogger, self).__init__()
|
|
17
|
+
|
|
18
|
+
@db_rollback
|
|
19
|
+
def create_tables(self, tables):
|
|
20
|
+
r"""
|
|
21
|
+
Documentation here
|
|
22
|
+
"""
|
|
23
|
+
if not self.check_connectivity():
|
|
24
|
+
|
|
25
|
+
return
|
|
26
|
+
|
|
27
|
+
self._db.create_tables(tables, safe=True)
|
|
28
|
+
self.__init_default_alarms_schema()
|
|
29
|
+
|
|
30
|
+
@db_rollback
|
|
31
|
+
def __init_default_alarms_schema(self):
|
|
32
|
+
r"""
|
|
33
|
+
Documentation here
|
|
34
|
+
"""
|
|
35
|
+
## Alarm Types
|
|
36
|
+
for alarm_type in TriggerType:
|
|
37
|
+
|
|
38
|
+
AlarmTypes.create(name=alarm_type.value)
|
|
39
|
+
|
|
40
|
+
## Alarm States
|
|
41
|
+
for alarm_state in AlarmState._states:
|
|
42
|
+
name = alarm_state.state
|
|
43
|
+
mnemonic = alarm_state.mnemonic
|
|
44
|
+
condition = alarm_state.process_condition
|
|
45
|
+
status = alarm_state.alarm_status
|
|
46
|
+
AlarmStates.create(name=name, mnemonic=mnemonic, condition=condition, status=status)
|
|
47
|
+
|
|
48
|
+
@db_rollback
|
|
49
|
+
def create(
|
|
50
|
+
self,
|
|
51
|
+
id:str,
|
|
52
|
+
name:str,
|
|
53
|
+
tag:str,
|
|
54
|
+
trigger_type:str,
|
|
55
|
+
trigger_value:float,
|
|
56
|
+
description:str):
|
|
57
|
+
r"""
|
|
58
|
+
Documentation here
|
|
59
|
+
"""
|
|
60
|
+
if not self.check_connectivity():
|
|
61
|
+
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
Alarms.create(
|
|
65
|
+
identifier=id,
|
|
66
|
+
name=name,
|
|
67
|
+
tag=tag,
|
|
68
|
+
trigger_type=trigger_type,
|
|
69
|
+
trigger_value=trigger_value,
|
|
70
|
+
description=description
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
@db_rollback
|
|
74
|
+
def get_alarms(self):
|
|
75
|
+
r"""
|
|
76
|
+
Documentation here
|
|
77
|
+
"""
|
|
78
|
+
if not self.check_connectivity():
|
|
79
|
+
|
|
80
|
+
return list()
|
|
81
|
+
|
|
82
|
+
alarms = Alarms.read_all()
|
|
83
|
+
|
|
84
|
+
if alarms:
|
|
85
|
+
|
|
86
|
+
return alarms
|
|
87
|
+
|
|
88
|
+
@db_rollback
|
|
89
|
+
def get_alarm_by_name(self, name:str)->Alarms|None:
|
|
90
|
+
r"""
|
|
91
|
+
Documentation here
|
|
92
|
+
"""
|
|
93
|
+
if not self.check_connectivity():
|
|
94
|
+
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
return Alarms.read_by_name(name=name)
|
|
98
|
+
|
|
99
|
+
@db_rollback
|
|
100
|
+
def get_lasts(self, lasts:int=10):
|
|
101
|
+
r"""
|
|
102
|
+
Documentation here
|
|
103
|
+
"""
|
|
104
|
+
if not self.is_history_logged:
|
|
105
|
+
|
|
106
|
+
return list()
|
|
107
|
+
|
|
108
|
+
if not self.check_connectivity():
|
|
109
|
+
|
|
110
|
+
return list()
|
|
111
|
+
|
|
112
|
+
return AlarmSummary.read_lasts(lasts=lasts)
|
|
113
|
+
|
|
114
|
+
@db_rollback
|
|
115
|
+
def filter_alarm_summary_by(
|
|
116
|
+
self,
|
|
117
|
+
states:list[str]=None,
|
|
118
|
+
names:list[str]=None,
|
|
119
|
+
tags:list[str]=None,
|
|
120
|
+
greater_than_timestamp:datetime=None,
|
|
121
|
+
less_than_timestamp:datetime=None,
|
|
122
|
+
timezone:str="UTC"
|
|
123
|
+
):
|
|
124
|
+
r"""
|
|
125
|
+
Documentation here
|
|
126
|
+
"""
|
|
127
|
+
if not self.is_history_logged:
|
|
128
|
+
|
|
129
|
+
return None
|
|
130
|
+
|
|
131
|
+
if not self.check_connectivity():
|
|
132
|
+
|
|
133
|
+
return list()
|
|
134
|
+
|
|
135
|
+
return AlarmSummary.filter_by(
|
|
136
|
+
states=states,
|
|
137
|
+
names=names,
|
|
138
|
+
tags=tags,
|
|
139
|
+
greater_than_timestamp=greater_than_timestamp,
|
|
140
|
+
less_than_timestamp=less_than_timestamp,
|
|
141
|
+
timezone=timezone
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
@db_rollback
|
|
145
|
+
def put(
|
|
146
|
+
self,
|
|
147
|
+
id:str,
|
|
148
|
+
name:str=None,
|
|
149
|
+
tag:str=None,
|
|
150
|
+
description:str=None,
|
|
151
|
+
alarm_type:str=None,
|
|
152
|
+
trigger_value:str=None,
|
|
153
|
+
state:str=None
|
|
154
|
+
):
|
|
155
|
+
if not self.check_connectivity():
|
|
156
|
+
|
|
157
|
+
return None
|
|
158
|
+
|
|
159
|
+
fields = dict()
|
|
160
|
+
alarm = Alarms.read_by_identifier(identifier=id)
|
|
161
|
+
if alarm:
|
|
162
|
+
if name:
|
|
163
|
+
fields["name"] = name
|
|
164
|
+
if tag:
|
|
165
|
+
fields["tag"] = tag
|
|
166
|
+
if description:
|
|
167
|
+
fields["description"] = description
|
|
168
|
+
if alarm_type:
|
|
169
|
+
alarm_type = AlarmTypes.read_by_name(name=alarm_type)
|
|
170
|
+
fields["trigger_type"] = alarm_type
|
|
171
|
+
if trigger_value:
|
|
172
|
+
fields["trigger_value"] = trigger_value
|
|
173
|
+
if state:
|
|
174
|
+
alarm_state = AlarmStates.get_or_none(name=state)
|
|
175
|
+
fields["state"] = alarm_state
|
|
176
|
+
query = Alarms.put(
|
|
177
|
+
id=alarm.id,
|
|
178
|
+
**fields
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
return query
|
|
182
|
+
|
|
183
|
+
@db_rollback
|
|
184
|
+
def delete(self, id:str):
|
|
185
|
+
r"""
|
|
186
|
+
Documentation here
|
|
187
|
+
"""
|
|
188
|
+
if not self.check_connectivity():
|
|
189
|
+
|
|
190
|
+
return None
|
|
191
|
+
|
|
192
|
+
alarm_state = AlarmStates.get_or_none(name="Out Of Service")
|
|
193
|
+
alarm = Alarms.read_by_identifier(identifier=id)
|
|
194
|
+
Alarms.put(
|
|
195
|
+
id=alarm.id,
|
|
196
|
+
state=alarm_state
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
@db_rollback
|
|
200
|
+
def create_record_on_alarm_summary(self, name:str, state:str, timestamp:datetime, ack_timestamp:datetime=None):
|
|
201
|
+
r"""
|
|
202
|
+
Documentation here
|
|
203
|
+
"""
|
|
204
|
+
if not self.is_history_logged:
|
|
205
|
+
|
|
206
|
+
return None
|
|
207
|
+
|
|
208
|
+
if self.check_connectivity():
|
|
209
|
+
|
|
210
|
+
AlarmSummary.create(name=name, state=state, timestamp=timestamp, ack_timestamp=ack_timestamp)
|
|
211
|
+
|
|
212
|
+
@db_rollback
|
|
213
|
+
def put_record_on_alarm_summary(self, name:str, state:str=None, ack_timestamp:datetime=None):
|
|
214
|
+
r"""
|
|
215
|
+
Documentation here
|
|
216
|
+
"""
|
|
217
|
+
if not self.check_connectivity():
|
|
218
|
+
|
|
219
|
+
return None
|
|
220
|
+
|
|
221
|
+
if not self.is_history_logged:
|
|
222
|
+
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
fields = dict()
|
|
226
|
+
alarm = AlarmSummary.read_by_name(name=name)
|
|
227
|
+
|
|
228
|
+
if alarm:
|
|
229
|
+
|
|
230
|
+
if ack_timestamp:
|
|
231
|
+
fields["ack_time"] = ack_timestamp
|
|
232
|
+
if state:
|
|
233
|
+
alarm_state = AlarmStates.get_or_none(name=state)
|
|
234
|
+
fields["state"] = alarm_state
|
|
235
|
+
|
|
236
|
+
if fields:
|
|
237
|
+
query = AlarmSummary.put(
|
|
238
|
+
id=alarm.id,
|
|
239
|
+
**fields
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
return query
|
|
243
|
+
|
|
244
|
+
@db_rollback
|
|
245
|
+
def get_alarm_summary(self):
|
|
246
|
+
r"""
|
|
247
|
+
Documentation here
|
|
248
|
+
"""
|
|
249
|
+
if not self.is_history_logged:
|
|
250
|
+
|
|
251
|
+
return None
|
|
252
|
+
|
|
253
|
+
if not self.check_connectivity():
|
|
254
|
+
|
|
255
|
+
return list()
|
|
256
|
+
|
|
257
|
+
return AlarmSummary.read_all()
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
class AlarmsLoggerEngine(BaseEngine):
|
|
261
|
+
r"""
|
|
262
|
+
Alarms logger Engine class for Tag thread-safe database logging.
|
|
263
|
+
|
|
264
|
+
"""
|
|
265
|
+
|
|
266
|
+
def __init__(self):
|
|
267
|
+
|
|
268
|
+
super(AlarmsLoggerEngine, self).__init__()
|
|
269
|
+
self.logger = AlarmsLogger()
|
|
270
|
+
|
|
271
|
+
def create(
|
|
272
|
+
self,
|
|
273
|
+
id:str,
|
|
274
|
+
name:str,
|
|
275
|
+
tag:str,
|
|
276
|
+
trigger_type:str,
|
|
277
|
+
trigger_value:float,
|
|
278
|
+
description:str
|
|
279
|
+
):
|
|
280
|
+
|
|
281
|
+
_query = dict()
|
|
282
|
+
_query["action"] = "create"
|
|
283
|
+
_query["parameters"] = dict()
|
|
284
|
+
_query["parameters"]["id"] = id
|
|
285
|
+
_query["parameters"]["name"] = name
|
|
286
|
+
_query["parameters"]["tag"] = tag
|
|
287
|
+
_query["parameters"]["trigger_type"] = trigger_type
|
|
288
|
+
_query["parameters"]["trigger_value"] = trigger_value
|
|
289
|
+
_query["parameters"]["description"] = description
|
|
290
|
+
|
|
291
|
+
return self.query(_query)
|
|
292
|
+
|
|
293
|
+
def get_lasts(
|
|
294
|
+
self,
|
|
295
|
+
lasts:int=1
|
|
296
|
+
):
|
|
297
|
+
|
|
298
|
+
_query = dict()
|
|
299
|
+
_query["action"] = "get_lasts"
|
|
300
|
+
_query["parameters"] = dict()
|
|
301
|
+
_query["parameters"]["lasts"] = lasts
|
|
302
|
+
|
|
303
|
+
return self.query(_query)
|
|
304
|
+
|
|
305
|
+
def get_alarms(self):
|
|
306
|
+
|
|
307
|
+
_query = dict()
|
|
308
|
+
_query["action"] = "get_alarms"
|
|
309
|
+
_query["parameters"] = dict()
|
|
310
|
+
|
|
311
|
+
return self.query(_query)
|
|
312
|
+
|
|
313
|
+
def get_alarm_by_name(self, name:str):
|
|
314
|
+
|
|
315
|
+
_query = dict()
|
|
316
|
+
_query["action"] = "get_alarm_by_name"
|
|
317
|
+
_query["parameters"] = dict()
|
|
318
|
+
_query["parameters"]["name"] = name
|
|
319
|
+
|
|
320
|
+
return self.query(_query)
|
|
321
|
+
|
|
322
|
+
def filter_alarm_summary_by(
|
|
323
|
+
self,
|
|
324
|
+
names:list[str]=None,
|
|
325
|
+
states:list[int]=None,
|
|
326
|
+
tags:list[int]=None,
|
|
327
|
+
greater_than_timestamp:datetime=None,
|
|
328
|
+
less_than_timestamp:datetime=None,
|
|
329
|
+
timezone:str='UTC'
|
|
330
|
+
):
|
|
331
|
+
|
|
332
|
+
_query = dict()
|
|
333
|
+
_query["action"] = "filter_alarm_summary_by"
|
|
334
|
+
_query["parameters"] = dict()
|
|
335
|
+
_query["parameters"]["names"] = names
|
|
336
|
+
_query["parameters"]["states"] = states
|
|
337
|
+
_query["parameters"]["tags"] = tags
|
|
338
|
+
_query["parameters"]["greater_than_timestamp"] = greater_than_timestamp
|
|
339
|
+
_query["parameters"]["less_than_timestamp"] = less_than_timestamp
|
|
340
|
+
_query["parameters"]["timezone"] = timezone
|
|
341
|
+
|
|
342
|
+
return self.query(_query)
|
|
343
|
+
|
|
344
|
+
def create_record_on_alarm_summary(self, name:str, state:str, timestamp:datetime, ack_timestamp:datetime=None):
|
|
345
|
+
|
|
346
|
+
_query = dict()
|
|
347
|
+
_query["action"] = "create_record_on_alarm_summary"
|
|
348
|
+
_query["parameters"] = dict()
|
|
349
|
+
_query["parameters"]["name"] = name
|
|
350
|
+
_query["parameters"]["state"] = state
|
|
351
|
+
_query["parameters"]["timestamp"] = timestamp
|
|
352
|
+
_query["parameters"]["ack_timestamp"] = ack_timestamp
|
|
353
|
+
|
|
354
|
+
return self.query(_query)
|
|
355
|
+
|
|
356
|
+
def put_record_on_alarm_summary(
|
|
357
|
+
self,
|
|
358
|
+
name:str,
|
|
359
|
+
state:str=None,
|
|
360
|
+
ack_timestamp:datetime=None
|
|
361
|
+
):
|
|
362
|
+
_query = dict()
|
|
363
|
+
_query["action"] = "put_record_on_alarm_summary"
|
|
364
|
+
_query["parameters"] = dict()
|
|
365
|
+
_query["parameters"]["name"] = name
|
|
366
|
+
_query["parameters"]["state"] = state
|
|
367
|
+
_query["parameters"]["ack_timestamp"] = ack_timestamp
|
|
368
|
+
|
|
369
|
+
return self.query(_query)
|
|
370
|
+
|
|
371
|
+
def put(
|
|
372
|
+
self,
|
|
373
|
+
id:str,
|
|
374
|
+
name:str=None,
|
|
375
|
+
tag:str=None,
|
|
376
|
+
description:str=None,
|
|
377
|
+
alarm_type:str=None,
|
|
378
|
+
trigger_value:str=None,
|
|
379
|
+
state:str=None
|
|
380
|
+
):
|
|
381
|
+
_query = dict()
|
|
382
|
+
_query["action"] = "put"
|
|
383
|
+
_query["parameters"] = dict()
|
|
384
|
+
_query["parameters"]["id"] = id
|
|
385
|
+
_query["parameters"]["name"] = name
|
|
386
|
+
_query["parameters"]["tag"] = tag
|
|
387
|
+
_query["parameters"]["description"] = description
|
|
388
|
+
_query["parameters"]["alarm_type"] = alarm_type
|
|
389
|
+
_query["parameters"]["trigger_value"] = trigger_value
|
|
390
|
+
_query["parameters"]["state"] = state
|
|
391
|
+
|
|
392
|
+
return self.query(_query)
|
|
393
|
+
|
|
394
|
+
def delete(self, id:str):
|
|
395
|
+
r"""
|
|
396
|
+
Documentation here
|
|
397
|
+
"""
|
|
398
|
+
_query = dict()
|
|
399
|
+
_query["action"] = "delete"
|
|
400
|
+
_query["parameters"] = dict()
|
|
401
|
+
_query["parameters"]["id"] = id
|
|
402
|
+
return self.query(_query)
|
|
403
|
+
|
|
404
|
+
def get_alarm_summary(self):
|
|
405
|
+
r"""
|
|
406
|
+
Documentation here
|
|
407
|
+
"""
|
|
408
|
+
_query = dict()
|
|
409
|
+
_query["action"] = "get_alarm_summary"
|
|
410
|
+
_query["parameters"] = dict()
|
|
411
|
+
|
|
412
|
+
return self.query(_query)
|
|
413
|
+
|
|
414
|
+
def create_tables(self, tables):
|
|
415
|
+
r"""
|
|
416
|
+
Create default PyHades database tables
|
|
417
|
+
|
|
418
|
+
['TagTrend', 'TagValue']
|
|
419
|
+
|
|
420
|
+
**Parameters**
|
|
421
|
+
|
|
422
|
+
* **tables** (list) list of database model
|
|
423
|
+
|
|
424
|
+
**Returns** `None`
|
|
425
|
+
"""
|
|
426
|
+
self.logger.create_tables(tables)
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import threading, logging
|
|
2
|
+
from ..singleton import Singleton
|
|
3
|
+
from ..dbmodels import (
|
|
4
|
+
Variables,
|
|
5
|
+
Units,
|
|
6
|
+
DataTypes
|
|
7
|
+
)
|
|
8
|
+
from ..variables import VARIABLES, DATATYPES
|
|
9
|
+
|
|
10
|
+
class BaseLogger(Singleton):
|
|
11
|
+
|
|
12
|
+
def __init__(self):
|
|
13
|
+
|
|
14
|
+
self._db = None
|
|
15
|
+
self.is_history_logged = True
|
|
16
|
+
|
|
17
|
+
def set_db(self, db):
|
|
18
|
+
r"""Documentation here
|
|
19
|
+
"""
|
|
20
|
+
self._db = db
|
|
21
|
+
|
|
22
|
+
def get_db(self):
|
|
23
|
+
r"""
|
|
24
|
+
Documentation here
|
|
25
|
+
"""
|
|
26
|
+
return self._db
|
|
27
|
+
|
|
28
|
+
def check_connectivity(self):
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
|
|
32
|
+
if self._db:
|
|
33
|
+
|
|
34
|
+
self._db.execute_sql('SELECT 1;')
|
|
35
|
+
|
|
36
|
+
return True
|
|
37
|
+
|
|
38
|
+
return False
|
|
39
|
+
|
|
40
|
+
except:
|
|
41
|
+
|
|
42
|
+
return False
|
|
43
|
+
|
|
44
|
+
def set_is_history_logged(self, value:bool=False):
|
|
45
|
+
r"""Documentation here
|
|
46
|
+
"""
|
|
47
|
+
self.is_history_logged = value
|
|
48
|
+
|
|
49
|
+
def stop_db(self):
|
|
50
|
+
r""""
|
|
51
|
+
Documentation here
|
|
52
|
+
"""
|
|
53
|
+
try:
|
|
54
|
+
if self._db:
|
|
55
|
+
self._db.close()
|
|
56
|
+
self._db = None
|
|
57
|
+
except:
|
|
58
|
+
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
def create_tables(self, tables):
|
|
62
|
+
r"""
|
|
63
|
+
Documentation here
|
|
64
|
+
"""
|
|
65
|
+
if not self._db:
|
|
66
|
+
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
self._db.create_tables(tables, safe=True)
|
|
70
|
+
self.__init_default_variables_schema()
|
|
71
|
+
self.__init_default_datatypes_schema()
|
|
72
|
+
self.__init_default_roles_schema()
|
|
73
|
+
|
|
74
|
+
def __init_default_roles_schema(self):
|
|
75
|
+
r"""
|
|
76
|
+
Documentatio here
|
|
77
|
+
"""
|
|
78
|
+
from ..dbmodels import Roles
|
|
79
|
+
for role in Roles.__defaults__:
|
|
80
|
+
|
|
81
|
+
if not Roles.name_exist(name=role['name']):
|
|
82
|
+
|
|
83
|
+
Roles.create(**role)
|
|
84
|
+
|
|
85
|
+
def __init_default_variables_schema(self):
|
|
86
|
+
r"""
|
|
87
|
+
Documentation here
|
|
88
|
+
"""
|
|
89
|
+
for variable, units in VARIABLES.items():
|
|
90
|
+
|
|
91
|
+
if not Variables.name_exist(variable):
|
|
92
|
+
|
|
93
|
+
Variables.create(name=variable)
|
|
94
|
+
|
|
95
|
+
for name, unit in units.items():
|
|
96
|
+
|
|
97
|
+
if not Units.name_exist(unit):
|
|
98
|
+
|
|
99
|
+
Units.create(name=name, unit=unit, variable=variable)
|
|
100
|
+
|
|
101
|
+
def __init_default_datatypes_schema(self):
|
|
102
|
+
r"""
|
|
103
|
+
Documentation here
|
|
104
|
+
"""
|
|
105
|
+
for datatype in DATATYPES:
|
|
106
|
+
|
|
107
|
+
DataTypes.create(name=datatype["value"])
|
|
108
|
+
|
|
109
|
+
def drop_tables(self, tables):
|
|
110
|
+
r"""
|
|
111
|
+
Documentation here
|
|
112
|
+
"""
|
|
113
|
+
if not self._db:
|
|
114
|
+
|
|
115
|
+
return
|
|
116
|
+
|
|
117
|
+
self._db.drop_tables(tables, safe=True)
|
|
118
|
+
|
|
119
|
+
class BaseEngine(Singleton):
|
|
120
|
+
r"""
|
|
121
|
+
Alarms logger Engine class for Tag thread-safe database logging.
|
|
122
|
+
"""
|
|
123
|
+
logger = BaseLogger()
|
|
124
|
+
|
|
125
|
+
def __init__(self):
|
|
126
|
+
|
|
127
|
+
super(BaseEngine, self).__init__()
|
|
128
|
+
self._request_lock = threading.Lock()
|
|
129
|
+
self._response_lock = threading.Lock()
|
|
130
|
+
self._response = None
|
|
131
|
+
self._response_lock.acquire()
|
|
132
|
+
|
|
133
|
+
def set_db(self, db):
|
|
134
|
+
r"""
|
|
135
|
+
Sets the database, it supports SQLite and Postgres,
|
|
136
|
+
in case of SQLite, the filename must be provided.
|
|
137
|
+
|
|
138
|
+
if app mode is "Development" you must use SQLite Databse
|
|
139
|
+
|
|
140
|
+
**Parameters:**
|
|
141
|
+
|
|
142
|
+
* **dbfile** (str): a path to database file.
|
|
143
|
+
* *drop_table** (bool): If you want to drop table.
|
|
144
|
+
* **cascade** (bool): if there are some table dependency, drop it as well
|
|
145
|
+
* **kwargs**: Same attributes to a postgres connection.
|
|
146
|
+
|
|
147
|
+
**Returns:** `None`
|
|
148
|
+
|
|
149
|
+
Usage:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
>>> app.set_db(dbfile="app.db")
|
|
153
|
+
```
|
|
154
|
+
"""
|
|
155
|
+
self.logger.set_db(db)
|
|
156
|
+
|
|
157
|
+
def stop_db(self):
|
|
158
|
+
r"""
|
|
159
|
+
Documentation here
|
|
160
|
+
"""
|
|
161
|
+
self.logger.stop_db()
|
|
162
|
+
|
|
163
|
+
def get_db(self):
|
|
164
|
+
r"""
|
|
165
|
+
Returns a DB object
|
|
166
|
+
"""
|
|
167
|
+
return self.logger.get_db()
|
|
168
|
+
|
|
169
|
+
def query(self, query:dict)->dict:
|
|
170
|
+
r"""
|
|
171
|
+
Documentation here
|
|
172
|
+
"""
|
|
173
|
+
self.request(query)
|
|
174
|
+
result = self.response()
|
|
175
|
+
if result["result"]:
|
|
176
|
+
return result["response"]
|
|
177
|
+
|
|
178
|
+
def request(self, query:dict):
|
|
179
|
+
r"""Documentation here
|
|
180
|
+
|
|
181
|
+
# Parameters
|
|
182
|
+
|
|
183
|
+
-
|
|
184
|
+
|
|
185
|
+
# Returns
|
|
186
|
+
|
|
187
|
+
-
|
|
188
|
+
"""
|
|
189
|
+
self._request_lock.acquire()
|
|
190
|
+
action = query["action"]
|
|
191
|
+
error_msg = f"Error in BaseEngine: {action}"
|
|
192
|
+
|
|
193
|
+
try:
|
|
194
|
+
|
|
195
|
+
if hasattr(self.logger, action):
|
|
196
|
+
|
|
197
|
+
method = getattr(self.logger, action)
|
|
198
|
+
|
|
199
|
+
if 'parameters' in query:
|
|
200
|
+
|
|
201
|
+
resp = method(**query["parameters"])
|
|
202
|
+
|
|
203
|
+
else:
|
|
204
|
+
|
|
205
|
+
resp = method()
|
|
206
|
+
|
|
207
|
+
self.__true_response(resp)
|
|
208
|
+
|
|
209
|
+
except Exception as e:
|
|
210
|
+
|
|
211
|
+
self.__log_error(e, error_msg)
|
|
212
|
+
|
|
213
|
+
self._response_lock.release()
|
|
214
|
+
|
|
215
|
+
def __log_error(self, e:Exception, msg:str):
|
|
216
|
+
r"""
|
|
217
|
+
Documentation here
|
|
218
|
+
"""
|
|
219
|
+
logger = logging.getLogger("pyautomation")
|
|
220
|
+
logger.error(f"{e} Message: {msg}")
|
|
221
|
+
self._response = {
|
|
222
|
+
"result": False,
|
|
223
|
+
"response": None
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
def response(self):
|
|
227
|
+
r"""Documentation here
|
|
228
|
+
|
|
229
|
+
# Parameters
|
|
230
|
+
|
|
231
|
+
-
|
|
232
|
+
|
|
233
|
+
# Returns
|
|
234
|
+
|
|
235
|
+
-
|
|
236
|
+
"""
|
|
237
|
+
self._response_lock.acquire()
|
|
238
|
+
result = self._response
|
|
239
|
+
self._request_lock.release()
|
|
240
|
+
return result
|
|
241
|
+
|
|
242
|
+
def __true_response(self, resp):
|
|
243
|
+
r"""
|
|
244
|
+
Documentation here
|
|
245
|
+
"""
|
|
246
|
+
self._response = {
|
|
247
|
+
"result": True,
|
|
248
|
+
"response": resp
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
def __getstate__(self):
|
|
252
|
+
|
|
253
|
+
self._response_lock.release()
|
|
254
|
+
state = self.__dict__.copy()
|
|
255
|
+
del state['_request_lock']
|
|
256
|
+
del state['_response_lock']
|
|
257
|
+
return state
|
|
258
|
+
|
|
259
|
+
def __setstate__(self, state):
|
|
260
|
+
|
|
261
|
+
self.__dict__.update(state)
|
|
262
|
+
self._request_lock = threading.Lock()
|
|
263
|
+
self._response_lock = threading.Lock()
|
|
264
|
+
|
|
265
|
+
self._response_lock.acquire()
|