PyAutomationIO 1.1.3__tar.gz → 1.1.4__tar.gz
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.
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/PKG-INFO +13 -2
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/PyAutomationIO.egg-info/PKG-INFO +13 -2
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/PyAutomationIO.egg-info/SOURCES.txt +3 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/README.md +12 -1
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/__init__.py +1 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/core.py +136 -3
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/__init__.py +3 -1
- pyautomationio-1.1.4/automation/modules/settings/__init__.py +7 -0
- pyautomationio-1.1.4/automation/modules/settings/resources/__init__.py +5 -0
- pyautomationio-1.1.4/automation/modules/settings/resources/settings.py +79 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/utils/decorators.py +7 -1
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/workers/logger.py +1 -1
- pyautomationio-1.1.4/version.py +2 -0
- pyautomationio-1.1.3/version.py +0 -2
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/LICENSE +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/MANIFEST.in +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/PyAutomationIO.egg-info/dependency_links.txt +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/PyAutomationIO.egg-info/requires.txt +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/PyAutomationIO.egg-info/top_level.txt +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/alarms/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/alarms/states.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/alarms/trigger.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/buffer.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/dbmodels/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/dbmodels/alarms.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/dbmodels/core.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/dbmodels/events.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/dbmodels/logs.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/dbmodels/machines.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/dbmodels/opcua.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/dbmodels/opcua_server.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/dbmodels/tags.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/dbmodels/users.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/extensions/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/extensions/api.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/extensions/cors.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/filter/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/iad/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/iad/frozen_data.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/iad/out_of_range.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/iad/outliers.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/logger/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/logger/alarms.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/logger/core.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/logger/datalogger.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/logger/events.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/logger/logdict.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/logger/logs.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/logger/machines.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/logger/opcua_server.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/logger/users.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/managers/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/managers/alarms.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/managers/db.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/managers/opcua_client.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/managers/state_machine.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/models.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/alarms/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/alarms/resources/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/alarms/resources/alarms.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/alarms/resources/summary.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/events/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/events/resources/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/events/resources/events.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/events/resources/logs.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/tags/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/tags/resources/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/tags/resources/tags.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/users/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/users/resources/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/users/resources/models/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/users/resources/models/roles.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/users/resources/models/users.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/users/resources/roles.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/users/resources/users.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/users/roles.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/users/users.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/opcua/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/opcua/models.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/opcua/subscription.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/alarms.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/alarms_history.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/assets/styles.css +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/callbacks/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/callbacks/alarms.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/callbacks/alarms_summary.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/callbacks/db.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/callbacks/filter.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/callbacks/machines.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/callbacks/machines_detailed.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/callbacks/opcua.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/callbacks/opcua_server.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/callbacks/tags.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/callbacks/trends.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/communications.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/components/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/components/alarms.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/components/alarms_summary.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/components/database.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/components/gaussian_filter.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/components/machines.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/components/opcua.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/components/opcua_server.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/components/tags.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/components/trends.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/database.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/filter.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/machines.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/machines_detailed.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/main.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/opcua_server.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/tags.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/trends.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/singleton.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/state_machine.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/tags/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/tags/cvt.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/tags/filter.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/tags/tag.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/tests/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/tests/test_alarms.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/tests/test_core.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/tests/test_unit.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/tests/test_user.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/utils/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/utils/observer.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/utils/units.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/adimentional.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/current.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/density.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/eng_time.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/force.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/length.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/mass.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/mass_flow.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/percentage.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/power.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/pressure.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/temperature.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/volume.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/variables/volumetric_flow.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/workers/__init__.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/workers/state_machine.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/workers/worker.py +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/requirements.txt +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/setup.cfg +0 -0
- {pyautomationio-1.1.3 → pyautomationio-1.1.4}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyAutomationIO
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.4
|
|
4
4
|
Summary: A python library to develop automation continuous tasks using sync or async concurrent threads
|
|
5
5
|
Home-page: https://github.com/know-ai/PyAutomation
|
|
6
6
|
Author: KnowAI
|
|
@@ -117,10 +117,22 @@ services:
|
|
|
117
117
|
volumes:
|
|
118
118
|
- automation_db:/app/db
|
|
119
119
|
- automation_logs:/app/logs
|
|
120
|
+
logging:
|
|
121
|
+
driver: "json-file"
|
|
122
|
+
options:
|
|
123
|
+
max-size: "10m" # Rota cuando llega a 10MB
|
|
124
|
+
max-file: "3" # Guarda máximo 3 archivos (30MB total)
|
|
120
125
|
environment:
|
|
121
126
|
OPCUA_SERVER_PORT: ${AUTOMATION_OPCUA_SERVER_PORT}
|
|
122
127
|
LOG_MAX_BYTES: ${AUTOMATION_LOG_MAX_BYTES}
|
|
123
128
|
LOG_BACKUP_COUNT: ${AUTOMATION_LOG_BACKUP_COUNT}
|
|
129
|
+
tmpfs:
|
|
130
|
+
- /tmp:size=500k
|
|
131
|
+
deploy:
|
|
132
|
+
resources:
|
|
133
|
+
limits:
|
|
134
|
+
cpus: "0.5"
|
|
135
|
+
memory: 256M
|
|
124
136
|
healthcheck:
|
|
125
137
|
test: ["CMD", "python", "/app/healthcheck.py"]
|
|
126
138
|
interval: 15s
|
|
@@ -130,7 +142,6 @@ services:
|
|
|
130
142
|
volumes:
|
|
131
143
|
automation_db:
|
|
132
144
|
automation_logs:
|
|
133
|
-
|
|
134
145
|
```
|
|
135
146
|
|
|
136
147
|
Start the docker compose file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyAutomationIO
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.4
|
|
4
4
|
Summary: A python library to develop automation continuous tasks using sync or async concurrent threads
|
|
5
5
|
Home-page: https://github.com/know-ai/PyAutomation
|
|
6
6
|
Author: KnowAI
|
|
@@ -117,10 +117,22 @@ services:
|
|
|
117
117
|
volumes:
|
|
118
118
|
- automation_db:/app/db
|
|
119
119
|
- automation_logs:/app/logs
|
|
120
|
+
logging:
|
|
121
|
+
driver: "json-file"
|
|
122
|
+
options:
|
|
123
|
+
max-size: "10m" # Rota cuando llega a 10MB
|
|
124
|
+
max-file: "3" # Guarda máximo 3 archivos (30MB total)
|
|
120
125
|
environment:
|
|
121
126
|
OPCUA_SERVER_PORT: ${AUTOMATION_OPCUA_SERVER_PORT}
|
|
122
127
|
LOG_MAX_BYTES: ${AUTOMATION_LOG_MAX_BYTES}
|
|
123
128
|
LOG_BACKUP_COUNT: ${AUTOMATION_LOG_BACKUP_COUNT}
|
|
129
|
+
tmpfs:
|
|
130
|
+
- /tmp:size=500k
|
|
131
|
+
deploy:
|
|
132
|
+
resources:
|
|
133
|
+
limits:
|
|
134
|
+
cpus: "0.5"
|
|
135
|
+
memory: 256M
|
|
124
136
|
healthcheck:
|
|
125
137
|
test: ["CMD", "python", "/app/healthcheck.py"]
|
|
126
138
|
interval: 15s
|
|
@@ -130,7 +142,6 @@ services:
|
|
|
130
142
|
volumes:
|
|
131
143
|
automation_db:
|
|
132
144
|
automation_logs:
|
|
133
|
-
|
|
134
145
|
```
|
|
135
146
|
|
|
136
147
|
Start the docker compose file
|
|
@@ -60,6 +60,9 @@ automation/modules/events/__init__.py
|
|
|
60
60
|
automation/modules/events/resources/__init__.py
|
|
61
61
|
automation/modules/events/resources/events.py
|
|
62
62
|
automation/modules/events/resources/logs.py
|
|
63
|
+
automation/modules/settings/__init__.py
|
|
64
|
+
automation/modules/settings/resources/__init__.py
|
|
65
|
+
automation/modules/settings/resources/settings.py
|
|
63
66
|
automation/modules/tags/__init__.py
|
|
64
67
|
automation/modules/tags/resources/__init__.py
|
|
65
68
|
automation/modules/tags/resources/tags.py
|
|
@@ -64,10 +64,22 @@ services:
|
|
|
64
64
|
volumes:
|
|
65
65
|
- automation_db:/app/db
|
|
66
66
|
- automation_logs:/app/logs
|
|
67
|
+
logging:
|
|
68
|
+
driver: "json-file"
|
|
69
|
+
options:
|
|
70
|
+
max-size: "10m" # Rota cuando llega a 10MB
|
|
71
|
+
max-file: "3" # Guarda máximo 3 archivos (30MB total)
|
|
67
72
|
environment:
|
|
68
73
|
OPCUA_SERVER_PORT: ${AUTOMATION_OPCUA_SERVER_PORT}
|
|
69
74
|
LOG_MAX_BYTES: ${AUTOMATION_LOG_MAX_BYTES}
|
|
70
75
|
LOG_BACKUP_COUNT: ${AUTOMATION_LOG_BACKUP_COUNT}
|
|
76
|
+
tmpfs:
|
|
77
|
+
- /tmp:size=500k
|
|
78
|
+
deploy:
|
|
79
|
+
resources:
|
|
80
|
+
limits:
|
|
81
|
+
cpus: "0.5"
|
|
82
|
+
memory: 256M
|
|
71
83
|
healthcheck:
|
|
72
84
|
test: ["CMD", "python", "/app/healthcheck.py"]
|
|
73
85
|
interval: 15s
|
|
@@ -77,7 +89,6 @@ services:
|
|
|
77
89
|
volumes:
|
|
78
90
|
automation_db:
|
|
79
91
|
automation_logs:
|
|
80
|
-
|
|
81
92
|
```
|
|
82
93
|
|
|
83
94
|
Start the docker compose file
|
|
@@ -1066,6 +1066,50 @@ class PyAutomation(Singleton):
|
|
|
1066
1066
|
logging.warning(message)
|
|
1067
1067
|
return None
|
|
1068
1068
|
|
|
1069
|
+
@logging_error_handler
|
|
1070
|
+
def set_app_config(self, **kwargs):
|
|
1071
|
+
r"""
|
|
1072
|
+
Update app configuration into app_config.json
|
|
1073
|
+
"""
|
|
1074
|
+
try:
|
|
1075
|
+
config_path = os.path.join(".", "db", "app_config.json")
|
|
1076
|
+
config = {}
|
|
1077
|
+
|
|
1078
|
+
if os.path.exists(config_path):
|
|
1079
|
+
with open(config_path, 'r') as f:
|
|
1080
|
+
config = json.load(f)
|
|
1081
|
+
|
|
1082
|
+
config.update(kwargs)
|
|
1083
|
+
|
|
1084
|
+
with open(config_path, 'w') as f:
|
|
1085
|
+
json.dump(config, f, indent=4)
|
|
1086
|
+
|
|
1087
|
+
except Exception as e:
|
|
1088
|
+
logging.error(f"Failed to persist app config: {e}")
|
|
1089
|
+
|
|
1090
|
+
@logging_error_handler
|
|
1091
|
+
def get_app_config(self) -> dict:
|
|
1092
|
+
r"""
|
|
1093
|
+
Get app configuration from app_config.json
|
|
1094
|
+
"""
|
|
1095
|
+
try:
|
|
1096
|
+
config_path = os.path.join(".", "db", "app_config.json")
|
|
1097
|
+
if os.path.exists(config_path):
|
|
1098
|
+
with open(config_path, 'r') as f:
|
|
1099
|
+
return json.load(f)
|
|
1100
|
+
else:
|
|
1101
|
+
# Create default config if not exists
|
|
1102
|
+
default_config = {
|
|
1103
|
+
"logger_period": 10.0,
|
|
1104
|
+
"log_level": 20
|
|
1105
|
+
}
|
|
1106
|
+
self.set_app_config(**default_config)
|
|
1107
|
+
return default_config
|
|
1108
|
+
|
|
1109
|
+
except Exception as e:
|
|
1110
|
+
logging.error(f"Failed to read app config: {e}")
|
|
1111
|
+
return {"logger_period": 10.0, "log_level": 20}
|
|
1112
|
+
|
|
1069
1113
|
@logging_error_handler
|
|
1070
1114
|
@validate_types(output=bool)
|
|
1071
1115
|
def is_db_connected(self):
|
|
@@ -1655,6 +1699,18 @@ class PyAutomation(Singleton):
|
|
|
1655
1699
|
|
|
1656
1700
|
**Returns:** `None`
|
|
1657
1701
|
"""
|
|
1702
|
+
str_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
1703
|
+
logging.critical(f"{str_date} Starting app with configuration:")
|
|
1704
|
+
logging.critical(f"{str_date} Logger period: {self.get_app_config().get('logger_period', 10.0)} seconds")
|
|
1705
|
+
logging.critical(f"{str_date} Log max bytes: {self.get_app_config().get('log_max_bytes', 10 * 1024 * 1024)} bytes")
|
|
1706
|
+
logging.critical(f"{str_date} Log backup count: {self.get_app_config().get('log_backup_count', 3)} backups")
|
|
1707
|
+
logging.critical(f"{str_date} Log level: {self.get_app_config().get('log_level', 20)}")
|
|
1708
|
+
print(f"[INFO] {str_date} Starting app with configuration:")
|
|
1709
|
+
print(f"[INFO] {str_date} Logger period: {self.get_app_config().get('logger_period', 10.0)} seconds")
|
|
1710
|
+
print(f"[INFO] {str_date} Log max bytes: {self.get_app_config().get('log_max_bytes', 10 * 1024 * 1024)} bytes")
|
|
1711
|
+
print(f"[INFO] {str_date} Log backup count: {self.get_app_config().get('log_backup_count', 3)} backups")
|
|
1712
|
+
print(f"[INFO] {str_date} Log level: {self.get_app_config().get('log_level', 20)}")
|
|
1713
|
+
|
|
1658
1714
|
self.safe_start(test=test, create_tables=create_tables, machines=machines)
|
|
1659
1715
|
self.create_system_user()
|
|
1660
1716
|
|
|
@@ -1694,6 +1750,23 @@ class PyAutomation(Singleton):
|
|
|
1694
1750
|
self._create_tables = create_tables
|
|
1695
1751
|
self.__start_logger()
|
|
1696
1752
|
self.__start_workers(test=test, machines=machines)
|
|
1753
|
+
str_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
1754
|
+
logging.critical(f"{str_date} App started successfully")
|
|
1755
|
+
print(f"[INFO] {str_date} App started successfully")
|
|
1756
|
+
|
|
1757
|
+
@logging_error_handler
|
|
1758
|
+
@validate_types(period=float, output=None)
|
|
1759
|
+
def update_logger_period(self, period:float):
|
|
1760
|
+
r"""
|
|
1761
|
+
Update logger worker period
|
|
1762
|
+
"""
|
|
1763
|
+
if hasattr(self, 'db_worker'):
|
|
1764
|
+
self.db_worker._period = period
|
|
1765
|
+
str_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
1766
|
+
logging.info(f"{str_date} Logger period updated to {period} seconds")
|
|
1767
|
+
print(f"[INFO] {str_date} Logger period updated to {period} seconds")
|
|
1768
|
+
|
|
1769
|
+
self.set_app_config(logger_period=period)
|
|
1697
1770
|
|
|
1698
1771
|
@logging_error_handler
|
|
1699
1772
|
@validate_types(output=None)
|
|
@@ -1723,8 +1796,11 @@ class PyAutomation(Singleton):
|
|
|
1723
1796
|
* DASWorker
|
|
1724
1797
|
"""
|
|
1725
1798
|
if self._create_tables:
|
|
1799
|
+
|
|
1800
|
+
app_config = self.get_app_config()
|
|
1801
|
+
logger_period = float(app_config.get("logger_period", 10.0))
|
|
1726
1802
|
|
|
1727
|
-
self.db_worker = LoggerWorker(self.db_manager)
|
|
1803
|
+
self.db_worker = LoggerWorker(self.db_manager, period=logger_period)
|
|
1728
1804
|
self.connect_to_db(test=test)
|
|
1729
1805
|
self.db_worker.start()
|
|
1730
1806
|
|
|
@@ -1753,6 +1829,50 @@ class PyAutomation(Singleton):
|
|
|
1753
1829
|
if hasattr(self, 'subscription_monitor'):
|
|
1754
1830
|
self.subscription_monitor.stop()
|
|
1755
1831
|
|
|
1832
|
+
@logging_error_handler
|
|
1833
|
+
@validate_types(level=int, output=None)
|
|
1834
|
+
def update_log_level(self, level:int):
|
|
1835
|
+
r"""
|
|
1836
|
+
Update logger level dynamically and persist it.
|
|
1837
|
+
"""
|
|
1838
|
+
self._logging_level = level
|
|
1839
|
+
|
|
1840
|
+
# Update root logger
|
|
1841
|
+
root_logger = logging.getLogger()
|
|
1842
|
+
root_logger.setLevel(level)
|
|
1843
|
+
|
|
1844
|
+
# Update app logger
|
|
1845
|
+
app_logger = logging.getLogger("pyautomation")
|
|
1846
|
+
app_logger.setLevel(level)
|
|
1847
|
+
|
|
1848
|
+
logging.log(level, f"Log level updated to {level}")
|
|
1849
|
+
|
|
1850
|
+
# Persist to config
|
|
1851
|
+
self.set_app_config(log_level=level)
|
|
1852
|
+
|
|
1853
|
+
@logging_error_handler
|
|
1854
|
+
@validate_types(max_bytes=int, backup_count=int, output=None)
|
|
1855
|
+
def update_log_config(self, max_bytes:int, backup_count:int):
|
|
1856
|
+
r"""
|
|
1857
|
+
Update logger configuration (maxBytes and backupCount) dynamically and persist it.
|
|
1858
|
+
"""
|
|
1859
|
+
# 1. Update runtime logger
|
|
1860
|
+
root_logger = logging.getLogger()
|
|
1861
|
+
for handler in root_logger.handlers:
|
|
1862
|
+
if isinstance(handler, RotatingFileHandler):
|
|
1863
|
+
# Update handler properties
|
|
1864
|
+
handler.maxBytes = max_bytes
|
|
1865
|
+
handler.backupCount = backup_count
|
|
1866
|
+
# Trigger rollover if needed (optional, or wait for next write)
|
|
1867
|
+
# handler.doRollover()
|
|
1868
|
+
str_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
1869
|
+
logging.info(f"{str_date} Log configuration updated: maxBytes={max_bytes}, backupCount={backup_count}")
|
|
1870
|
+
print(f"[INFO] {str_date} Log configuration updated: maxBytes={max_bytes}, backupCount={backup_count}")
|
|
1871
|
+
break
|
|
1872
|
+
|
|
1873
|
+
# 2. Persist to config
|
|
1874
|
+
self.set_app_config(log_max_bytes=max_bytes, log_backup_count=backup_count)
|
|
1875
|
+
|
|
1756
1876
|
@logging_error_handler
|
|
1757
1877
|
@validate_types(output=None)
|
|
1758
1878
|
def __start_logger(self)->None:
|
|
@@ -1768,13 +1888,26 @@ class PyAutomation(Singleton):
|
|
|
1768
1888
|
logging.getLogger('opcua').setLevel(logging.CRITICAL)
|
|
1769
1889
|
# Configure root logger with rotating file handler (size-based)
|
|
1770
1890
|
root_logger = logging.getLogger()
|
|
1891
|
+
|
|
1892
|
+
# Load level from config
|
|
1893
|
+
app_config = self.get_app_config()
|
|
1894
|
+
# Default logging.INFO (20) if not set in config, overriding __init__ warning default
|
|
1895
|
+
persisted_level = int(app_config.get('log_level', logging.INFO))
|
|
1896
|
+
self._logging_level = persisted_level
|
|
1897
|
+
|
|
1771
1898
|
root_logger.setLevel(self._logging_level)
|
|
1772
1899
|
# Clear existing handlers to avoid duplicates
|
|
1773
1900
|
for _h in list(root_logger.handlers):
|
|
1774
1901
|
root_logger.removeHandler(_h)
|
|
1775
1902
|
|
|
1776
|
-
|
|
1777
|
-
|
|
1903
|
+
app_config = self.get_app_config()
|
|
1904
|
+
# Default fallback to env or hardcoded
|
|
1905
|
+
env_max_bytes = int(os.environ.get('LOG_MAX_BYTES', 10 * 1024 * 1024))
|
|
1906
|
+
env_backup_count = int(os.environ.get('LOG_BACKUP_COUNT', 3))
|
|
1907
|
+
|
|
1908
|
+
max_bytes = int(app_config.get('log_max_bytes', env_max_bytes))
|
|
1909
|
+
backup_count = int(app_config.get('log_backup_count', env_backup_count))
|
|
1910
|
+
|
|
1778
1911
|
handler = RotatingFileHandler(
|
|
1779
1912
|
filename=self._log_file,
|
|
1780
1913
|
maxBytes=max_bytes,
|
|
@@ -7,8 +7,10 @@ def init_app(app):
|
|
|
7
7
|
from ..modules.alarms.resources import init_app as init_alarms
|
|
8
8
|
from ..modules.users.resources import init_app as init_users
|
|
9
9
|
from ..modules.events.resources import init_app as init_events
|
|
10
|
+
from ..modules.settings.resources import init_app as init_settings
|
|
10
11
|
|
|
11
12
|
init_tags()
|
|
12
13
|
init_alarms()
|
|
13
14
|
init_users()
|
|
14
|
-
init_events()
|
|
15
|
+
init_events()
|
|
16
|
+
init_settings()
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from flask_restx import Namespace, Resource, fields
|
|
2
|
+
from .... import PyAutomation
|
|
3
|
+
from ....extensions.api import api
|
|
4
|
+
from ....extensions import _api as Api
|
|
5
|
+
|
|
6
|
+
ns = Namespace('Settings', description='Settings')
|
|
7
|
+
app = PyAutomation()
|
|
8
|
+
|
|
9
|
+
settings_model = api.model("settings_model", {
|
|
10
|
+
'logger_period': fields.Float(required=False, min=1.0, description='Logger worker period in seconds'),
|
|
11
|
+
'log_max_bytes': fields.Integer(required=False, min=1024, description='Max bytes for log file rotation'),
|
|
12
|
+
'log_backup_count': fields.Integer(required=False, min=1, description='Number of backup log files to keep'),
|
|
13
|
+
'log_level': fields.Integer(required=False, min=0, max=50, description='Logging level (0=NOTSET, 10=DEBUG, 20=INFO, 30=WARNING, 40=ERROR, 50=CRITICAL)')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
@ns.route('/update')
|
|
17
|
+
class SettingsUpdateResource(Resource):
|
|
18
|
+
|
|
19
|
+
@api.doc(security='apikey')
|
|
20
|
+
@Api.token_required(auth=True)
|
|
21
|
+
@ns.expect(settings_model)
|
|
22
|
+
def put(self):
|
|
23
|
+
"""
|
|
24
|
+
Update application settings (Logger period, Log rotation config, Log level)
|
|
25
|
+
"""
|
|
26
|
+
data = api.payload
|
|
27
|
+
|
|
28
|
+
# 1. Update Logger Worker Period
|
|
29
|
+
if 'logger_period' in data:
|
|
30
|
+
logger_period = data['logger_period']
|
|
31
|
+
if logger_period < 1.0:
|
|
32
|
+
return "Logger period must be >= 1.0", 400
|
|
33
|
+
app.update_logger_period(logger_period)
|
|
34
|
+
|
|
35
|
+
# 2. Update Log Rotation Config
|
|
36
|
+
if 'log_max_bytes' in data and 'log_backup_count' in data:
|
|
37
|
+
max_bytes = data['log_max_bytes']
|
|
38
|
+
backup_count = data['log_backup_count']
|
|
39
|
+
|
|
40
|
+
if max_bytes < 1024:
|
|
41
|
+
return "log_max_bytes must be >= 1024", 400
|
|
42
|
+
if backup_count < 1:
|
|
43
|
+
return "log_backup_count must be >= 1", 400
|
|
44
|
+
|
|
45
|
+
app.update_log_config(max_bytes, backup_count)
|
|
46
|
+
|
|
47
|
+
elif 'log_max_bytes' in data or 'log_backup_count' in data:
|
|
48
|
+
return "Both log_max_bytes and log_backup_count must be provided together", 400
|
|
49
|
+
|
|
50
|
+
# 3. Update Log Level
|
|
51
|
+
if 'log_level' in data:
|
|
52
|
+
log_level = data['log_level']
|
|
53
|
+
# Basic validation for standard levels
|
|
54
|
+
if log_level not in [0, 10, 20, 30, 40, 50]:
|
|
55
|
+
return "Invalid log_level. Use standard Python logging levels (10, 20, 30, 40, 50)", 400
|
|
56
|
+
|
|
57
|
+
app.update_log_level(log_level)
|
|
58
|
+
|
|
59
|
+
return "Settings updated", 200
|
|
60
|
+
|
|
61
|
+
@ns.route('/logger_period')
|
|
62
|
+
class LoggerPeriodResource(Resource):
|
|
63
|
+
|
|
64
|
+
@api.doc(security='apikey')
|
|
65
|
+
@Api.token_required(auth=True)
|
|
66
|
+
@ns.expect(settings_model)
|
|
67
|
+
def put(self):
|
|
68
|
+
"""
|
|
69
|
+
Update logger worker period
|
|
70
|
+
"""
|
|
71
|
+
logger_period = api.payload.get('logger_period')
|
|
72
|
+
|
|
73
|
+
if logger_period < 1.0:
|
|
74
|
+
return "Logger period must be >= 1.0", 400
|
|
75
|
+
|
|
76
|
+
app.update_logger_period(logger_period)
|
|
77
|
+
|
|
78
|
+
return "Logger period updated", 200
|
|
79
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import functools, logging, sys
|
|
1
|
+
import functools, logging, sys, datetime
|
|
2
2
|
from ..modules.users.users import User, Users
|
|
3
3
|
from ..logger.events import EventsLoggerEngine
|
|
4
4
|
|
|
@@ -159,6 +159,8 @@ def validate_types(**validations):
|
|
|
159
159
|
message = f"Expected output type ({counter}) {expected}, but got {type(result[counter])} in func {func}"
|
|
160
160
|
logger = logging.getLogger("pyautomation")
|
|
161
161
|
logger.error(message)
|
|
162
|
+
str_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
163
|
+
print(f"[ERROR] {str_date} {message}")
|
|
162
164
|
raise TypeError(message)
|
|
163
165
|
|
|
164
166
|
else:
|
|
@@ -167,6 +169,8 @@ def validate_types(**validations):
|
|
|
167
169
|
message = f"Expected output type {_output}, but got {type(result)} in func {func}"
|
|
168
170
|
logger = logging.getLogger("pyautomation")
|
|
169
171
|
logger.error(message)
|
|
172
|
+
str_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
173
|
+
print(f"[ERROR] {str_date} {message}")
|
|
170
174
|
raise TypeError(message)
|
|
171
175
|
|
|
172
176
|
return result
|
|
@@ -201,6 +205,8 @@ def logging_error_handler(func, args, kwargs):
|
|
|
201
205
|
})
|
|
202
206
|
logger = logging.getLogger("pyautomation")
|
|
203
207
|
logger.error(msg=msg)
|
|
208
|
+
str_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
209
|
+
print(f"[ERROR] {str_date} {msg}")
|
|
204
210
|
|
|
205
211
|
@decorator
|
|
206
212
|
def db_rollback(func, args, kwargs):
|
pyautomationio-1.1.3/version.py
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/alarms/resources/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/alarms/resources/summary.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/events/resources/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/users/resources/__init__.py
RENAMED
|
File without changes
|
{pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/users/resources/models/__init__.py
RENAMED
|
File without changes
|
{pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/users/resources/models/roles.py
RENAMED
|
File without changes
|
{pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/modules/users/resources/models/users.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/callbacks/machines_detailed.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyautomationio-1.1.3 → pyautomationio-1.1.4}/automation/pages/components/gaussian_filter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|