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,335 @@
|
|
|
1
|
+
import secrets
|
|
2
|
+
from werkzeug.security import generate_password_hash, check_password_hash
|
|
3
|
+
from ...singleton import Singleton
|
|
4
|
+
from .roles import Role, Roles
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class User:
|
|
9
|
+
r"""
|
|
10
|
+
Documentation here
|
|
11
|
+
"""
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
username:str,
|
|
15
|
+
role:Role,
|
|
16
|
+
email:str,
|
|
17
|
+
password:str,
|
|
18
|
+
name:str=None,
|
|
19
|
+
lastname:str=None,
|
|
20
|
+
identifier:str=None):
|
|
21
|
+
|
|
22
|
+
self.identifier = secrets.token_hex(4)
|
|
23
|
+
if identifier:
|
|
24
|
+
self.identifier = identifier
|
|
25
|
+
self.username = username
|
|
26
|
+
self.role = role
|
|
27
|
+
self.email = email
|
|
28
|
+
self.password = password
|
|
29
|
+
self.name = name
|
|
30
|
+
self.lastname = lastname
|
|
31
|
+
self.token = None
|
|
32
|
+
|
|
33
|
+
def logout(self):
|
|
34
|
+
r"""
|
|
35
|
+
Documentation here
|
|
36
|
+
"""
|
|
37
|
+
self.token = None
|
|
38
|
+
|
|
39
|
+
def serialize(self):
|
|
40
|
+
r"""
|
|
41
|
+
Documentation here
|
|
42
|
+
"""
|
|
43
|
+
return {
|
|
44
|
+
"identifier": self.identifier,
|
|
45
|
+
"username": self.username,
|
|
46
|
+
"role": self.role.serialize(),
|
|
47
|
+
"email": self.email,
|
|
48
|
+
"name": self.name,
|
|
49
|
+
"lastname": self.lastname
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class Auth:
|
|
54
|
+
r"""
|
|
55
|
+
Documentation here
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
def login(self, user:User, password:str, token:str)->bool:
|
|
59
|
+
r"""
|
|
60
|
+
Documentation here
|
|
61
|
+
"""
|
|
62
|
+
if self.decode_password(user=user, password=password):
|
|
63
|
+
|
|
64
|
+
if token:
|
|
65
|
+
|
|
66
|
+
user.token = token
|
|
67
|
+
|
|
68
|
+
else:
|
|
69
|
+
|
|
70
|
+
user.token = self.encode(secrets.token_hex(4))
|
|
71
|
+
|
|
72
|
+
return True
|
|
73
|
+
|
|
74
|
+
return False
|
|
75
|
+
|
|
76
|
+
def verify_credentials(self, user:User, password:str)->bool:
|
|
77
|
+
r"""
|
|
78
|
+
Documentation here
|
|
79
|
+
"""
|
|
80
|
+
if self.decode_password(user=user, password=password):
|
|
81
|
+
|
|
82
|
+
return True
|
|
83
|
+
|
|
84
|
+
return False
|
|
85
|
+
|
|
86
|
+
def logout(self, user:User)->None:
|
|
87
|
+
r"""
|
|
88
|
+
Documentation here
|
|
89
|
+
"""
|
|
90
|
+
user.logout()
|
|
91
|
+
|
|
92
|
+
def encode(self, value:str)->str:
|
|
93
|
+
|
|
94
|
+
return generate_password_hash(value)
|
|
95
|
+
|
|
96
|
+
def decode_password(self, user:User, password:str)->str:
|
|
97
|
+
|
|
98
|
+
return check_password_hash(user.password, password)
|
|
99
|
+
|
|
100
|
+
def decode_token(self, user:User, token:str)->str:
|
|
101
|
+
|
|
102
|
+
return check_password_hash(user.token, token)
|
|
103
|
+
|
|
104
|
+
def signup(
|
|
105
|
+
self,
|
|
106
|
+
username:str,
|
|
107
|
+
role:Role,
|
|
108
|
+
email:str,
|
|
109
|
+
password:str,
|
|
110
|
+
name:str=None,
|
|
111
|
+
lastname:str=None,
|
|
112
|
+
identifier:str=None,
|
|
113
|
+
encode_password:bool=True
|
|
114
|
+
)->User:
|
|
115
|
+
r"""
|
|
116
|
+
Documentation here
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
return User(
|
|
120
|
+
username=username,
|
|
121
|
+
role=role,
|
|
122
|
+
email=email,
|
|
123
|
+
password=self.encode(value=password) if encode_password else password,
|
|
124
|
+
name=name,
|
|
125
|
+
lastname=lastname,
|
|
126
|
+
identifier=identifier if identifier else secrets.token_hex(4)
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class Users(Singleton):
|
|
131
|
+
r"""
|
|
132
|
+
Documentation here
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
def __init__(self):
|
|
136
|
+
|
|
137
|
+
self.__auth = Auth()
|
|
138
|
+
self.__reset()
|
|
139
|
+
|
|
140
|
+
def __reset(self):
|
|
141
|
+
|
|
142
|
+
self.active_users = dict() # Save by token
|
|
143
|
+
self.__by_identifier = dict()
|
|
144
|
+
self.__by_username = dict()
|
|
145
|
+
self.__by_email = dict()
|
|
146
|
+
|
|
147
|
+
def login(self, password:str, token:str=None, username:str=None, email:str=None):
|
|
148
|
+
r"""
|
|
149
|
+
Documentation here
|
|
150
|
+
"""
|
|
151
|
+
if username or email:
|
|
152
|
+
|
|
153
|
+
if username:
|
|
154
|
+
|
|
155
|
+
if not self.check_username(username=username):
|
|
156
|
+
|
|
157
|
+
return None, f"{username} is not valid"
|
|
158
|
+
|
|
159
|
+
user = self.get_by_username(username=username)
|
|
160
|
+
|
|
161
|
+
elif email:
|
|
162
|
+
|
|
163
|
+
if not self.check_email(email=email):
|
|
164
|
+
|
|
165
|
+
return None, f"{email} is not valid"
|
|
166
|
+
|
|
167
|
+
user = self.get_by_email(email=email)
|
|
168
|
+
|
|
169
|
+
if self.__auth.login(user=user, password=password, token=token):
|
|
170
|
+
|
|
171
|
+
self.active_users[user.token] = user
|
|
172
|
+
|
|
173
|
+
return user, f"Login successful"
|
|
174
|
+
|
|
175
|
+
else:
|
|
176
|
+
|
|
177
|
+
raise ValueError(f"You must submit username or email")
|
|
178
|
+
|
|
179
|
+
def logout(self, token:str)->None:
|
|
180
|
+
r"""
|
|
181
|
+
Documentation here
|
|
182
|
+
"""
|
|
183
|
+
if token in self.active_users:
|
|
184
|
+
|
|
185
|
+
user = self.active_users.pop(token)
|
|
186
|
+
|
|
187
|
+
self.__auth.logout(user=user)
|
|
188
|
+
|
|
189
|
+
def signup(self,
|
|
190
|
+
username:str,
|
|
191
|
+
role_name:str,
|
|
192
|
+
email:str,
|
|
193
|
+
password:str,
|
|
194
|
+
name:str=None,
|
|
195
|
+
lastname:str=None,
|
|
196
|
+
identifier:str=None,
|
|
197
|
+
encode_password:bool=True
|
|
198
|
+
)->tuple:
|
|
199
|
+
r"""
|
|
200
|
+
Documentation here
|
|
201
|
+
"""
|
|
202
|
+
message = f"{username} created successfully"
|
|
203
|
+
if not self.check_username(username=username):
|
|
204
|
+
|
|
205
|
+
if not self.check_email(email=email):
|
|
206
|
+
|
|
207
|
+
roles = Roles()
|
|
208
|
+
role = roles.get_by_name(name=role_name)
|
|
209
|
+
|
|
210
|
+
if role:
|
|
211
|
+
|
|
212
|
+
user = self.__auth.signup(
|
|
213
|
+
username=username,
|
|
214
|
+
role=role,
|
|
215
|
+
email=email,
|
|
216
|
+
password=password,
|
|
217
|
+
name=name,
|
|
218
|
+
lastname=lastname,
|
|
219
|
+
identifier=identifier,
|
|
220
|
+
encode_password=encode_password
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
self.__by_identifier[user.identifier] = user
|
|
224
|
+
self.__by_username[user.username] = user
|
|
225
|
+
self.__by_email[user.email] = user
|
|
226
|
+
return user, message
|
|
227
|
+
|
|
228
|
+
else:
|
|
229
|
+
|
|
230
|
+
return None, f"role: {role_name} not exists"
|
|
231
|
+
|
|
232
|
+
else:
|
|
233
|
+
|
|
234
|
+
return None, f"Email: {email} already exists"
|
|
235
|
+
|
|
236
|
+
else:
|
|
237
|
+
|
|
238
|
+
return None, f"username: {username} already exists"
|
|
239
|
+
|
|
240
|
+
def verify_credentials(self, password:str, username:str=None, email:str=None)->bool:
|
|
241
|
+
r"""
|
|
242
|
+
Documentation here
|
|
243
|
+
"""
|
|
244
|
+
if username or email:
|
|
245
|
+
|
|
246
|
+
if username:
|
|
247
|
+
|
|
248
|
+
if not self.check_username(username=username):
|
|
249
|
+
|
|
250
|
+
return False, f"{username} is not valid"
|
|
251
|
+
|
|
252
|
+
user = self.get_by_username(username=username)
|
|
253
|
+
|
|
254
|
+
elif email:
|
|
255
|
+
|
|
256
|
+
if not self.check_email(email=email):
|
|
257
|
+
|
|
258
|
+
return False, f"{email} is not valid"
|
|
259
|
+
|
|
260
|
+
user = self.get_by_email(email=email)
|
|
261
|
+
|
|
262
|
+
return self.__auth.verify_credentials(user=user, password=password), f"Credentials valid"
|
|
263
|
+
|
|
264
|
+
else:
|
|
265
|
+
|
|
266
|
+
return False, "You must submit username or email"
|
|
267
|
+
|
|
268
|
+
def get(self, identifier:str)->User:
|
|
269
|
+
r"""
|
|
270
|
+
Documentation here
|
|
271
|
+
"""
|
|
272
|
+
if identifier in self.__by_identifier:
|
|
273
|
+
|
|
274
|
+
return self.__by_identifier[identifier]
|
|
275
|
+
|
|
276
|
+
def get_active_user(self, token:str)->User:
|
|
277
|
+
r"""
|
|
278
|
+
Documentation here
|
|
279
|
+
"""
|
|
280
|
+
if token in self.active_users:
|
|
281
|
+
|
|
282
|
+
return self.active_users[token]
|
|
283
|
+
|
|
284
|
+
def get_by_username(self, username:str)->User:
|
|
285
|
+
r"""
|
|
286
|
+
Documentation here
|
|
287
|
+
"""
|
|
288
|
+
if username in self.__by_username:
|
|
289
|
+
|
|
290
|
+
return self.__by_username[username]
|
|
291
|
+
|
|
292
|
+
def get_by_email(self, email:str)->User:
|
|
293
|
+
r"""
|
|
294
|
+
Documentation here
|
|
295
|
+
"""
|
|
296
|
+
if email in self.__by_email:
|
|
297
|
+
|
|
298
|
+
return self.__by_email[email]
|
|
299
|
+
|
|
300
|
+
def check_username(self, username:str)->bool:
|
|
301
|
+
r"""
|
|
302
|
+
Documentation here
|
|
303
|
+
"""
|
|
304
|
+
if self.get_by_username(username=username):
|
|
305
|
+
|
|
306
|
+
return True
|
|
307
|
+
|
|
308
|
+
return False
|
|
309
|
+
|
|
310
|
+
def check_email(self, email:str)->bool:
|
|
311
|
+
r"""
|
|
312
|
+
Documentation here
|
|
313
|
+
"""
|
|
314
|
+
if self.get_by_email(email=email):
|
|
315
|
+
|
|
316
|
+
return True
|
|
317
|
+
|
|
318
|
+
return False
|
|
319
|
+
|
|
320
|
+
def encode(self, value:str)->str:
|
|
321
|
+
|
|
322
|
+
return generate_password_hash(value)
|
|
323
|
+
|
|
324
|
+
def _delete_all(self):
|
|
325
|
+
|
|
326
|
+
self.__reset()
|
|
327
|
+
|
|
328
|
+
def serialize(self):
|
|
329
|
+
r"""
|
|
330
|
+
Documentation here
|
|
331
|
+
"""
|
|
332
|
+
return [user.serialize() for user in self.__by_username.values() if user.role.name.lower()!="sudo"]
|
|
333
|
+
|
|
334
|
+
users = Users()
|
|
335
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .models import Client
|