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,153 @@
|
|
|
1
|
+
import pytz
|
|
2
|
+
from peewee import CharField, TimestampField, ForeignKeyField, IntegerField, fn
|
|
3
|
+
from ..dbmodels.core import BaseModel
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from .users import Users
|
|
6
|
+
from ..modules.users.users import User
|
|
7
|
+
|
|
8
|
+
DATETIME_FORMAT = "%m/%d/%Y, %H:%M:%S.%f"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Events(BaseModel):
|
|
12
|
+
|
|
13
|
+
timestamp = TimestampField(utc=True)
|
|
14
|
+
message = CharField(max_length=256)
|
|
15
|
+
description = CharField(max_length=256, null=True)
|
|
16
|
+
classification = CharField(max_length=128, null=True)
|
|
17
|
+
priority = IntegerField(null=True)
|
|
18
|
+
criticity = IntegerField(null=True)
|
|
19
|
+
user = ForeignKeyField(Users, backref='events')
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def create(
|
|
23
|
+
cls,
|
|
24
|
+
message:str,
|
|
25
|
+
user:User,
|
|
26
|
+
description:str=None,
|
|
27
|
+
classification:str=None,
|
|
28
|
+
priority:int=None,
|
|
29
|
+
criticity:int=None,
|
|
30
|
+
timestamp:datetime=None
|
|
31
|
+
)->tuple:
|
|
32
|
+
|
|
33
|
+
if not isinstance(user, User):
|
|
34
|
+
|
|
35
|
+
return None, f"User {user} - {type(user)} must be an User Object"
|
|
36
|
+
|
|
37
|
+
user = Users.read_by_username(username=user.username)
|
|
38
|
+
|
|
39
|
+
if not timestamp:
|
|
40
|
+
|
|
41
|
+
timestamp = datetime.now(pytz.UTC)
|
|
42
|
+
|
|
43
|
+
if not isinstance(timestamp, datetime):
|
|
44
|
+
|
|
45
|
+
return None, f"Timestamp must be a datetime Object"
|
|
46
|
+
|
|
47
|
+
query = cls(
|
|
48
|
+
message=message,
|
|
49
|
+
user=user,
|
|
50
|
+
description=description,
|
|
51
|
+
classification=classification,
|
|
52
|
+
priority=priority,
|
|
53
|
+
criticity=criticity,
|
|
54
|
+
timestamp=timestamp
|
|
55
|
+
)
|
|
56
|
+
query.save()
|
|
57
|
+
|
|
58
|
+
return query, f"Event creation successful"
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def read_lasts(cls, lasts:int=1):
|
|
62
|
+
r"""
|
|
63
|
+
Documentation here
|
|
64
|
+
"""
|
|
65
|
+
events = cls.select().order_by(cls.id.desc()).limit(lasts)
|
|
66
|
+
|
|
67
|
+
return [event.serialize() for event in events]
|
|
68
|
+
|
|
69
|
+
@classmethod
|
|
70
|
+
def filter_by(
|
|
71
|
+
cls,
|
|
72
|
+
usernames:list[str]=None,
|
|
73
|
+
priorities:list[int]=None,
|
|
74
|
+
criticities:list[int]=None,
|
|
75
|
+
greater_than_timestamp:datetime=None,
|
|
76
|
+
less_than_timestamp:datetime=None,
|
|
77
|
+
description:str="",
|
|
78
|
+
message:str="",
|
|
79
|
+
classification:str="",
|
|
80
|
+
timezone:str='UTC'):
|
|
81
|
+
r"""
|
|
82
|
+
Documentation here
|
|
83
|
+
"""
|
|
84
|
+
_timezone = pytz.timezone(timezone)
|
|
85
|
+
query = cls.select()
|
|
86
|
+
|
|
87
|
+
if usernames:
|
|
88
|
+
subquery = Users.select(Users.id).where(Users.username.in_(usernames))
|
|
89
|
+
query = query.join(Users).where(Users.id.in_(subquery))
|
|
90
|
+
|
|
91
|
+
if priorities:
|
|
92
|
+
query = query.where(cls.priority.in_(priorities))
|
|
93
|
+
|
|
94
|
+
if criticities:
|
|
95
|
+
query = query.where(cls.criticity.in_(criticities))
|
|
96
|
+
|
|
97
|
+
if description:
|
|
98
|
+
query = query.where(fn.LOWER(cls.description).contains(description.lower()))
|
|
99
|
+
|
|
100
|
+
if message:
|
|
101
|
+
query = query.where(fn.LOWER(cls.message).contains(message.lower()))
|
|
102
|
+
|
|
103
|
+
if classification:
|
|
104
|
+
query = query.where(fn.LOWER(cls.classification).contains(classification.lower()))
|
|
105
|
+
|
|
106
|
+
if greater_than_timestamp:
|
|
107
|
+
greater_than_timestamp = _timezone.localize(datetime.strptime(greater_than_timestamp, '%Y-%m-%d %H:%M:%S.%f')).astimezone(pytz.UTC)
|
|
108
|
+
query = query.where(cls.timestamp > greater_than_timestamp)
|
|
109
|
+
|
|
110
|
+
if less_than_timestamp:
|
|
111
|
+
less_than_timestamp = _timezone.localize(datetime.strptime(less_than_timestamp, '%Y-%m-%d %H:%M:%S.%f')).astimezone(pytz.UTC)
|
|
112
|
+
query = query.where(cls.timestamp < less_than_timestamp)
|
|
113
|
+
|
|
114
|
+
query = query.order_by(cls.id.desc())
|
|
115
|
+
|
|
116
|
+
if not query.exists():
|
|
117
|
+
|
|
118
|
+
return []
|
|
119
|
+
|
|
120
|
+
return [event.serialize() for event in query]
|
|
121
|
+
|
|
122
|
+
@classmethod
|
|
123
|
+
def get_comments(cls, id:int):
|
|
124
|
+
r"""
|
|
125
|
+
Documentation here
|
|
126
|
+
"""
|
|
127
|
+
query = cls.read(id=id)
|
|
128
|
+
|
|
129
|
+
return [comment.serialize() for comment in query.logs]
|
|
130
|
+
|
|
131
|
+
def serialize(self)-> dict:
|
|
132
|
+
from .. import TIMEZONE, MANUFACTURER, SEGMENT
|
|
133
|
+
timestamp = self.timestamp
|
|
134
|
+
if timestamp:
|
|
135
|
+
|
|
136
|
+
timestamp = timestamp.astimezone(TIMEZONE)
|
|
137
|
+
timestamp = timestamp.strftime(DATETIME_FORMAT)
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
"id": self.id,
|
|
141
|
+
"timestamp": timestamp,
|
|
142
|
+
"user": self.user.serialize(),
|
|
143
|
+
"message": self.message,
|
|
144
|
+
"description": self.description,
|
|
145
|
+
"classification": self.classification,
|
|
146
|
+
"priority": self.priority,
|
|
147
|
+
"criticity": self.criticity,
|
|
148
|
+
"segment": SEGMENT,
|
|
149
|
+
"manufacturer": MANUFACTURER,
|
|
150
|
+
"has_comments": True if self.logs else False
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import pytz
|
|
2
|
+
from peewee import CharField, TimestampField, ForeignKeyField, fn
|
|
3
|
+
from ..dbmodels.core import BaseModel
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from .users import Users
|
|
6
|
+
from .events import Events
|
|
7
|
+
from .alarms import AlarmSummary, Alarms
|
|
8
|
+
from ..modules.users.users import User
|
|
9
|
+
|
|
10
|
+
DATETIME_FORMAT = "%m/%d/%Y, %H:%M:%S.%f"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Logs(BaseModel):
|
|
14
|
+
|
|
15
|
+
timestamp = TimestampField(utc=True)
|
|
16
|
+
message = CharField(max_length=256)
|
|
17
|
+
description = CharField(max_length=256, null=True)
|
|
18
|
+
classification = CharField(max_length=128, null=True)
|
|
19
|
+
user = ForeignKeyField(Users, backref='logs', on_delete='CASCADE')
|
|
20
|
+
alarm = ForeignKeyField(AlarmSummary, null=True, backref='logs', on_delete='CASCADE')
|
|
21
|
+
event = ForeignKeyField(Events, null=True, backref='logs', on_delete='CASCADE')
|
|
22
|
+
|
|
23
|
+
@classmethod
|
|
24
|
+
def create(
|
|
25
|
+
cls,
|
|
26
|
+
message:str,
|
|
27
|
+
user:User,
|
|
28
|
+
description:str=None,
|
|
29
|
+
classification:str=None,
|
|
30
|
+
alarm_summary_id:int=None,
|
|
31
|
+
event_id:int=None,
|
|
32
|
+
timestamp:datetime=None
|
|
33
|
+
)->tuple:
|
|
34
|
+
if not isinstance(user, User):
|
|
35
|
+
|
|
36
|
+
return None, f"User {user} - {type(user)} must be an User Object"
|
|
37
|
+
|
|
38
|
+
_user = Users.read_by_username(username=user.username)
|
|
39
|
+
|
|
40
|
+
if not timestamp:
|
|
41
|
+
|
|
42
|
+
timestamp = datetime.now()
|
|
43
|
+
|
|
44
|
+
if not isinstance(timestamp, datetime):
|
|
45
|
+
|
|
46
|
+
return None, f"Timestamp must be a datetime Object"
|
|
47
|
+
|
|
48
|
+
query = cls(
|
|
49
|
+
message=message,
|
|
50
|
+
user=_user,
|
|
51
|
+
description=description,
|
|
52
|
+
classification=classification,
|
|
53
|
+
timestamp=timestamp,
|
|
54
|
+
event=Events.get_or_none(id=event_id),
|
|
55
|
+
alarm=AlarmSummary.get_or_none(id=alarm_summary_id)
|
|
56
|
+
)
|
|
57
|
+
query.save()
|
|
58
|
+
|
|
59
|
+
return query, f"Event creation successful"
|
|
60
|
+
|
|
61
|
+
@classmethod
|
|
62
|
+
def read_lasts(cls, lasts:int=1):
|
|
63
|
+
r"""
|
|
64
|
+
Documentation here
|
|
65
|
+
"""
|
|
66
|
+
logs = cls.select().order_by(cls.id.desc()).limit(lasts)
|
|
67
|
+
|
|
68
|
+
return [log.serialize() for log in logs]
|
|
69
|
+
|
|
70
|
+
@classmethod
|
|
71
|
+
def filter_by(
|
|
72
|
+
cls,
|
|
73
|
+
usernames:list[str]=None,
|
|
74
|
+
alarm_names:list[str]=None,
|
|
75
|
+
event_ids:list[int]=None,
|
|
76
|
+
description:str="",
|
|
77
|
+
message:str="",
|
|
78
|
+
classification:str="",
|
|
79
|
+
greater_than_timestamp:datetime=None,
|
|
80
|
+
less_than_timestamp:datetime=None,
|
|
81
|
+
timezone:str='UTC'
|
|
82
|
+
):
|
|
83
|
+
r"""
|
|
84
|
+
Documentation here
|
|
85
|
+
"""
|
|
86
|
+
_timezone = pytz.timezone(timezone)
|
|
87
|
+
query = cls.select()
|
|
88
|
+
|
|
89
|
+
if usernames:
|
|
90
|
+
subquery = Users.select(Users.id).where(Users.username.in_(usernames))
|
|
91
|
+
query = query.join(Users).where(Users.id.in_(subquery))
|
|
92
|
+
|
|
93
|
+
if event_ids:
|
|
94
|
+
subquery = Events.select(Events.id).where(Events.id.in_(event_ids))
|
|
95
|
+
query = query.join(Events).where(Events.id.in_(subquery))
|
|
96
|
+
|
|
97
|
+
if alarm_names:
|
|
98
|
+
subquery = Alarms.select(Alarms.id).where(Alarms.name.in_(alarm_names))
|
|
99
|
+
alarm_subquery = AlarmSummary.select(AlarmSummary.id).join(Alarms).where(Alarms.id.in_(subquery))
|
|
100
|
+
query = query.join(AlarmSummary).where(AlarmSummary.id.in_(alarm_subquery))
|
|
101
|
+
|
|
102
|
+
if description:
|
|
103
|
+
query = query.where(fn.LOWER(cls.description).contains(description.lower()))
|
|
104
|
+
|
|
105
|
+
if message:
|
|
106
|
+
query = query.where(fn.LOWER(cls.message).contains(message.lower()))
|
|
107
|
+
|
|
108
|
+
if classification:
|
|
109
|
+
query = query.where(fn.LOWER(cls.classification).contains(classification.lower()))
|
|
110
|
+
|
|
111
|
+
if greater_than_timestamp:
|
|
112
|
+
greater_than_timestamp = _timezone.localize(datetime.strptime(greater_than_timestamp, '%Y-%m-%d %H:%M:%S.%f')).astimezone(pytz.UTC)
|
|
113
|
+
query = query.where(cls.timestamp > greater_than_timestamp)
|
|
114
|
+
|
|
115
|
+
if less_than_timestamp:
|
|
116
|
+
less_than_timestamp = _timezone.localize(datetime.strptime(less_than_timestamp, '%Y-%m-%d %H:%M:%S.%f')).astimezone(pytz.UTC)
|
|
117
|
+
query = query.where(cls.timestamp < less_than_timestamp)
|
|
118
|
+
|
|
119
|
+
query = query.order_by(cls.id.desc())
|
|
120
|
+
|
|
121
|
+
if not query.exists():
|
|
122
|
+
|
|
123
|
+
return []
|
|
124
|
+
|
|
125
|
+
return [log.serialize() for log in query]
|
|
126
|
+
|
|
127
|
+
def serialize(self)-> dict:
|
|
128
|
+
from .. import MANUFACTURER, SEGMENT, TIMEZONE
|
|
129
|
+
timestamp = self.timestamp
|
|
130
|
+
if timestamp:
|
|
131
|
+
timestamp = pytz.UTC.localize(timestamp).astimezone(TIMEZONE)
|
|
132
|
+
timestamp = timestamp.strftime(DATETIME_FORMAT)
|
|
133
|
+
|
|
134
|
+
_event = None
|
|
135
|
+
if self.event:
|
|
136
|
+
|
|
137
|
+
_event = self.event.serialize()
|
|
138
|
+
|
|
139
|
+
_alarm = None
|
|
140
|
+
if self.alarm:
|
|
141
|
+
|
|
142
|
+
_alarm = self.alarm.serialize()
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
"id": self.id,
|
|
146
|
+
"timestamp": timestamp,
|
|
147
|
+
"user": self.user.serialize(),
|
|
148
|
+
"message": self.message,
|
|
149
|
+
"description": self.description,
|
|
150
|
+
"classification": self.classification,
|
|
151
|
+
"event": _event,
|
|
152
|
+
"alarm": _alarm,
|
|
153
|
+
"segment": SEGMENT,
|
|
154
|
+
"manufacturer": MANUFACTURER
|
|
155
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
from peewee import CharField, IntegerField, ForeignKeyField, FloatField
|
|
2
|
+
from .core import BaseModel
|
|
3
|
+
from .tags import Tags
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Machines(BaseModel):
|
|
7
|
+
|
|
8
|
+
identifier = CharField(unique=True)
|
|
9
|
+
name = CharField(unique=True)
|
|
10
|
+
interval = FloatField()
|
|
11
|
+
threshold = FloatField(null=True)
|
|
12
|
+
on_delay = IntegerField(null=True)
|
|
13
|
+
description = CharField(max_length=128)
|
|
14
|
+
classification = CharField(max_length=128)
|
|
15
|
+
buffer_size = IntegerField()
|
|
16
|
+
buffer_roll_type = CharField(max_length=16)
|
|
17
|
+
criticity = IntegerField()
|
|
18
|
+
priority = IntegerField()
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def create(
|
|
22
|
+
cls,
|
|
23
|
+
identifier:str,
|
|
24
|
+
name:str,
|
|
25
|
+
interval:int,
|
|
26
|
+
description:str,
|
|
27
|
+
classification:str,
|
|
28
|
+
buffer_size:int,
|
|
29
|
+
buffer_roll_type:str,
|
|
30
|
+
criticity:int,
|
|
31
|
+
priority:int,
|
|
32
|
+
threshold:float=None,
|
|
33
|
+
on_delay:int=None
|
|
34
|
+
)-> dict:
|
|
35
|
+
|
|
36
|
+
result = dict()
|
|
37
|
+
data = dict()
|
|
38
|
+
|
|
39
|
+
if not cls.name_exist(name):
|
|
40
|
+
|
|
41
|
+
query = cls(
|
|
42
|
+
identifier=identifier,
|
|
43
|
+
name=name,
|
|
44
|
+
interval=interval,
|
|
45
|
+
description=description,
|
|
46
|
+
classification=classification,
|
|
47
|
+
buffer_size=buffer_size,
|
|
48
|
+
buffer_roll_type=buffer_roll_type,
|
|
49
|
+
criticity=criticity,
|
|
50
|
+
priority=priority,
|
|
51
|
+
threshold=threshold,
|
|
52
|
+
on_delay=on_delay
|
|
53
|
+
)
|
|
54
|
+
query.save()
|
|
55
|
+
|
|
56
|
+
message = f"Machine {name} created successfully"
|
|
57
|
+
data.update(query.serialize())
|
|
58
|
+
|
|
59
|
+
result.update(
|
|
60
|
+
{
|
|
61
|
+
'message': message,
|
|
62
|
+
'data': data
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
return result
|
|
66
|
+
|
|
67
|
+
message = f"Machine {name} is already into database"
|
|
68
|
+
result.update(
|
|
69
|
+
{
|
|
70
|
+
'message': message,
|
|
71
|
+
'data': data
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
return result
|
|
75
|
+
|
|
76
|
+
@classmethod
|
|
77
|
+
def read_by_name(cls, name:str)->bool:
|
|
78
|
+
query = cls.get_or_none(name=name)
|
|
79
|
+
|
|
80
|
+
if query is not None:
|
|
81
|
+
|
|
82
|
+
return query
|
|
83
|
+
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
@classmethod
|
|
87
|
+
def read_config(cls):
|
|
88
|
+
r"""
|
|
89
|
+
Select all records
|
|
90
|
+
|
|
91
|
+
You can use this method to retrieve all instances matching in the database.
|
|
92
|
+
|
|
93
|
+
This method is a shortcut that calls Model.select() with the given query.
|
|
94
|
+
|
|
95
|
+
**Parameters**
|
|
96
|
+
|
|
97
|
+
**Returns**
|
|
98
|
+
|
|
99
|
+
* **result:** (dict) --> {'message': (str), 'data': (list) row serialized}
|
|
100
|
+
"""
|
|
101
|
+
return {f"{query.name}": query.serialize() for query in cls.select()}
|
|
102
|
+
|
|
103
|
+
@classmethod
|
|
104
|
+
def name_exist(cls, name:str)->bool:
|
|
105
|
+
r"""
|
|
106
|
+
Verify is a name exist into database
|
|
107
|
+
|
|
108
|
+
**Parameters**
|
|
109
|
+
|
|
110
|
+
* **name:** (str) Variable name
|
|
111
|
+
|
|
112
|
+
**Returns**
|
|
113
|
+
|
|
114
|
+
* **bool:** If True, name exist into database
|
|
115
|
+
"""
|
|
116
|
+
query = cls.get_or_none(name=name)
|
|
117
|
+
|
|
118
|
+
if query is not None:
|
|
119
|
+
|
|
120
|
+
return True
|
|
121
|
+
|
|
122
|
+
return False
|
|
123
|
+
|
|
124
|
+
def get_tags(self):
|
|
125
|
+
|
|
126
|
+
return self.tags
|
|
127
|
+
|
|
128
|
+
def serialize(self)-> dict:
|
|
129
|
+
r"""
|
|
130
|
+
Serialize database record to a jsonable object
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
"id": self.id,
|
|
135
|
+
"identifier": self.identifier,
|
|
136
|
+
"name": self.name,
|
|
137
|
+
"interval": self.interval,
|
|
138
|
+
"description": self.description,
|
|
139
|
+
"classification": self.classification,
|
|
140
|
+
"buffer_size": self.buffer_size,
|
|
141
|
+
"buffer_roll_type": self.buffer_roll_type,
|
|
142
|
+
"criticity": self.criticity,
|
|
143
|
+
"priority": self.priority,
|
|
144
|
+
"threshold": self.threshold,
|
|
145
|
+
"on_delay": self.on_delay
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class TagsMachines(BaseModel):
|
|
150
|
+
|
|
151
|
+
tag = ForeignKeyField(Tags, backref="machines")
|
|
152
|
+
machine = ForeignKeyField(Machines, backref="tags")
|
|
153
|
+
default_tag_name = CharField(max_length=64, null=True)
|
|
154
|
+
|
|
155
|
+
@classmethod
|
|
156
|
+
def create(
|
|
157
|
+
cls,
|
|
158
|
+
tag_name:str,
|
|
159
|
+
machine_name:str,
|
|
160
|
+
default_tag_name:str=None
|
|
161
|
+
)-> dict:
|
|
162
|
+
|
|
163
|
+
tag = Tags.get_or_none(name=tag_name)
|
|
164
|
+
machine = Machines.get_or_none(name=machine_name)
|
|
165
|
+
|
|
166
|
+
if not cls.get_or_none(tag=tag, machine=machine):
|
|
167
|
+
|
|
168
|
+
query = cls(
|
|
169
|
+
tag=tag,
|
|
170
|
+
machine=machine,
|
|
171
|
+
default_tag_name=default_tag_name
|
|
172
|
+
)
|
|
173
|
+
query.save()
|
|
174
|
+
|
|
175
|
+
def serialize(self):
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
"machine": self.machine.serialize(),
|
|
179
|
+
"tag": self.tag.serialize(),
|
|
180
|
+
"default_tag_name": self.default_tag_name
|
|
181
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from peewee import CharField, IntegerField
|
|
2
|
+
from ..dbmodels.core import BaseModel
|
|
3
|
+
|
|
4
|
+
class OPCUA(BaseModel):
|
|
5
|
+
|
|
6
|
+
client_name = CharField(unique=True)
|
|
7
|
+
host = CharField()
|
|
8
|
+
port = IntegerField()
|
|
9
|
+
|
|
10
|
+
@classmethod
|
|
11
|
+
def create(cls, client_name:str, host:str, port:int):
|
|
12
|
+
r"""
|
|
13
|
+
You can use Model.create() to create a new model instance. This method accepts keyword arguments, where the keys correspond
|
|
14
|
+
to the names of the model's fields. A new instance is returned and a row is added to the table.
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
>>> AlarmsType.create(name='High-High')
|
|
18
|
+
{
|
|
19
|
+
'message': (str)
|
|
20
|
+
'data': (dict) {
|
|
21
|
+
'name': 'HIGH-HIGH'
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
This will INSERT a new row into the database. The primary key will automatically be retrieved and stored on the model instance.
|
|
27
|
+
|
|
28
|
+
**Parameters**
|
|
29
|
+
|
|
30
|
+
* **name:** (str), Industrial protocol name
|
|
31
|
+
|
|
32
|
+
**Returns**
|
|
33
|
+
|
|
34
|
+
* **result:** (dict) --> {'message': (str), 'data': (dict) row serialized}
|
|
35
|
+
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
if not cls.client_name_exist(client_name):
|
|
39
|
+
|
|
40
|
+
query = cls(client_name=client_name, host=host, port=port)
|
|
41
|
+
query.save()
|
|
42
|
+
|
|
43
|
+
return query
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def get_by_client_name(cls, client_name:str):
|
|
47
|
+
r"""
|
|
48
|
+
Documentation here
|
|
49
|
+
"""
|
|
50
|
+
return cls.get_or_none(client_name=client_name)
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def client_name_exist(cls, client_name:str):
|
|
54
|
+
r"""
|
|
55
|
+
Verify is a name exist into database
|
|
56
|
+
|
|
57
|
+
**Parameters**
|
|
58
|
+
|
|
59
|
+
* **name:** (str) Variable name
|
|
60
|
+
|
|
61
|
+
**Returns**
|
|
62
|
+
|
|
63
|
+
* **bool:** If True, name exist into database
|
|
64
|
+
"""
|
|
65
|
+
query = cls.get_or_none(client_name=client_name)
|
|
66
|
+
|
|
67
|
+
if query is not None:
|
|
68
|
+
|
|
69
|
+
return True
|
|
70
|
+
|
|
71
|
+
return False
|
|
72
|
+
|
|
73
|
+
def serialize(self):
|
|
74
|
+
r"""
|
|
75
|
+
Documentation here
|
|
76
|
+
"""
|
|
77
|
+
return {
|
|
78
|
+
"client_name": self.client_name,
|
|
79
|
+
"host": self.host,
|
|
80
|
+
"port": self.port
|
|
81
|
+
}
|