Integracja sztucznej inteligencji (AI) z programowaniem sterowników PLC rewolucjonizuje automatykę przemysłową, zwiększając efektywność, elastyczność oraz możliwości predykcyjne. Wykorzystanie narzędzi takich jak silnik skryptów Python w środowisku CODESYS oraz usług AI opartych na chmurze oferuje inżynierom nowatorskie podejścia do projektowania i zarządzania aplikacjami PLC.
Silnik skryptów Python w środowisku CODESYS
Silnik skryptów Python w środowisku CODESYS to zaawłansowane narzylędzie umożliwiające automatyzację różnorodnych zadań związanych z rozwojem oraz zarządzaniem projektami w środowisku CODESYS. Dzięki integracji skryptów IronPython, programiści mogą usprawniać procesy takie jak tworzenie projektów, konfiguracja urządzeń oraz generowanie kodu, co znacząco zwiększa efektywność i precyzję pracy.
Key functionalities accessible through the Python Script Engine include:
- System: Access to general CODESYS functionalities, such as exiting the application and handling the user interface.
- Projects: Management of projects, including loading, creating, saving, and closing projects.
- Online: Online functions like logging into devices and applications, managing access data, performing network scans, and gateway management.
- LibraryManager: Management of library repositories, including viewing, installation, and removal of libraries.
- DeviceRepository: Handling of device repositories, including import and export of device descriptions.
Skrypty mogą być wykonywane bezpośrednio z interfejsu systemu CODESYS Development lub dzięki wiersza poleceń, co pozwala na elastyczną integrację procesów automatyzacji z istniejącymi przepływami pracy.
Aby ułatwić tworzenie i edytowanie skryptów, CODESYS oferuje wtyczkę Python Editor. Narzędzie to zapewnia funkcje takie jak autouzupełnianie, podświetlanie składni, strukturyzacja kodu oraz inteligentne wcięcia, zwiększając tym samym produktywność podczas opracowywania rozwiązań automatyzacyjnych opartych na skryptach Pythona.
Dzięki wykorzystaniu silnika skryptowego Python, programiści mogą osiągnąć wyższy poziom automatyzacji i precyzji w zarządzaniu projektami w środowisku CODESYS, co przekłada się na bardziej wydajne i niezawodne procesy rozwoju.
Dla profesjonalistów z dziedziny automatyki przemysłowej precyzja oraz spójność są kluczowe. Silnik skryptowy Python w CODESYS oferuje zaawansowane możliwości automatyzacji powtarzalnych zadań, takich jak dodawanie urządzeń, tworzenie programów, importowanie bibliotek czy konfiguracja projektów — wszystko z chirurgiczną precyzją.
Domyślna ścieżka do plików stub silnika skryptowego to:
C:\Program Files\CODESYS 3.5.xx.xx\CODESYS\ScriptLib\Stubs\scriptengine
Ten folder zawiera wszystkie pliki stub języka Python niezbędne do interakcji ze skryptowym API środowiska CODESYS. Pliki te pełnią rolę interfejsu między twoim kodem Pythona a wewnętrznymi obiektami środowiska CODESYS.
Jak używać w VS Code
Aby włączyć funkcje takie jak autouzupełnianie kodu, podświetlanie składni oraz podpowiedzi typów podczas pisania skryptów CODESYS w Visual Studio Code, możesz zrobić następujące rzeczy:
Skopiuj folder scriptengine z domyślnej ścieżki:
C:\Program Files\CODESYS 3.5.xx.xx\CODESYS\ScriptLib\Stubs\scriptengine
Wklej go do katalogu twojego projektu Pythonowego, na przykład:
my-codesys-scripts/
├── scriptengine/
├── my_script.py
Takie ustawienie pozwala VS Code rozpoznać moduły specyficzne dla CODESYS, co pomaga efektywniej pisać, testować i debugować twoje skrypty automatyzacji — choćby poza środowiskiem CODESYS.
Przykładowe programy w silniku skryptowym Python do interakcji z CODESYS
Przykładowy program:
devId = None
devices = device_repository.get_all_devices("CODESYS Control Win V3")
for device in
devices:
devId = device.device_id
proj = projects.primary
# delete existing testdev device
existing = proj.find('testdev')
if
len(existing) >
0:
existing[0].remove()
# add device
proj.add('testdev', devId)
apps = proj.find('Application', True)
if
len(apps) >
0:
app = apps[0]
tc = app.create_task_configuration()
Co robi skrypt
Ten skrypt służy do tego, aby:
- Pobrać identyfikator urządzenia dla CODESYS Control Win V3,
- Usunąć z projektu dowolne istniejące urządzenie o nazwie „testdev”,
- Dodać nowe urządzenie, używając pobranego identyfikatora urządzenia,
- Utworzyć konfigurację zadań (Task Configuration) dla aplikacji w projekcie.
Wyjaśnienie skryptu – linia po linii
devId = None
devices = device_repository.get_all_devices("CODESYS Control Win V3")
for device in
devices:
devId = device.device_id
- Pobiera wszystkie dostępne urządzenia z repozytorium urządzeń (Device Repository) pasujące do typu „CODESYS Control Win V3”.
- W pętli przechodzi przez wyniki i zapisuje identyfikator urządzenia (device_id) ostatniego pasującego urządzenia do zmiennej devId.
W skryptach produkcyjnych zwykle należy wybrać konkretną wersję lub urządzenie, zamiast brać ostatnie urządzenie bez dokładnej kontroli.
proj = projects.primary
Gets the currently opened CODESYS project — this is the project that the script will modify.
# delete existing testdev device
existing = proj.find('testdev')
if
len(existing) >
0:
existing[0].remove()
- Przeszukuje projekt w celu znalezienia dowolnego urządzenia o nazwie testdev.
- Jeśli zostanie znalezione, usuwa istniejące urządzenie, aby uniknąć duplikatów.
- Dzięki temu skrypt jest idempotentny — bezpieczny do wielokrotnego uruchamiania.
# add device
proj.add('testdev', devId)
Adds a new device to the project with the name testdev, using
the device_id fetched earlier.
apps = proj.find('Application', True)
if
len(apps) >
0:
app = apps[0]
tc = app.create_task_configuration()
- Przeszukuje projekt, aby znaleźć obiekt Application (z opcją recursive = True).
- Jeśli zostanie znaleziony, pobiera pierwszy znaleziony obiekt i tworzy w nim konfigurację zadań
(Task Configuration).
- Konfiguracje zadań są potrzebne do definiowania zadań cyklicznych, takich jak MainTask lub VISU_TASK.
Podsumowanie
Ten skrypt:
- Dynamicznie znajduje urządzenie CODESYS,
- Zapewnia, iż projekt nie zawiera duplikatów,
- Czysto dodaje nowe urządzenie,
- Przygotowuje projekt poprzez utworzenie nowej konfiguracji zadań – gotowej do dodawania programów.
Więcej przykładowych skryptów:
Dodanie urządzenia wraz z konfiguracją zadań
# add device with a task configuration
proj.add('PLC', devId)
apps = proj.find('Application', True)
if
len(apps) >
0:
tc = apps[0].create_task_configuration()
# add task
task = tc.create_task('Task')
task.pous.add('PLC_PRG')
# proj = projects.open("C:\Users\Administrator\Documents\PL Przepompownia AI\Untitled1.project")
# devId = None
# devices = device_repository.get_all_devices("CODESYS Control Win V3")
# for device in
devices:
# devId = device.device_id
# proj = projects.primary
# # add device
# proj.add('PLC', devId)
# apps = proj.find('Application', True)
# if
len(apps) >
0:
# tc = apps[0].create_task_configuration()
# # add task
# task = tc.create_task('Task')
# task.pous.add('PLC_PRG')
Utwórz POU
proj = projects.primary # current project
found = proj.find("Application", True)
app = found[0]
# Create FB
mypou = app.create_pou("MyPou")
# Change declaration of the FB
implementation = mypou.textual_declaration.replace("""FUNCTION_BLOCK MyPou
VAR_INPUT
iValue : INT;
END_VAR
VAR_OUTPUT
END_VAR
VAR
END_VAR""")
# Change implementation of the FB
mypou.textual_implementation.replace("""iValue := iValue + 1;""")
# Add method to FB
dosomething = mypou.create_method("DoSomething", "INT")
# Change declaration of the method
dosomething.textual_declaration.replace("""METHOD DoSomething : INT
VAR_INPUT
iVal1 : INT;
iVal2 : INT;
END_VAR""")
# Change implementation of the method
dosomething.textual_implementation.replace("""DoSomething := iVal1 + iVal2;""")
# # Find the pou and delete it
# found = app.find("MyPou")
# if found and len(found) ==
1:
# found[0].remove()
# else:
# print("POU 'MyPou' was not found")
Utwórz listę zmiennych globalnych i trwałych:
# Get the primary project or open a project
proj = projects.primary # Use the currently open project
# Find the Application object
found = proj.find("Application", True)
app = found[0]
# Create a Global Variable List (GVL)
gvl = app.create_gvl("GVL_Process")
# Define the global variables in the GVL
gvl.textual_declaration.replace("""VAR_GLOBAL
// System Configuration
g_xSystemEnabled : BOOL :=
TRUE; // System enable flag
g_xEmergencyStop : BOOL :=
FALSE; // Emergency stop status
g_xMaintenanceMode : BOOL :=
FALSE; // Maintenance mode flag
// Process Variables
g_rTemperature : REAL; // Process temperature
g_rPressure : REAL; // Process pressure
g_rFlowRate : REAL; // Flow rate
g_rLevel : REAL; // Tank level
// Control Parameters
g_rTempSetpoint : REAL :=
25.0; // Temperature setpoint
g_rPressSetpoint : REAL :=
2.5; // Pressure setpoint
g_rFlowSetpoint : REAL :=
100.0; // Flow rate setpoint
g_rLevelSetpoint : REAL :=
50.0; // Level setpoint
// Alarms
g_xTempAlarm : BOOL; // Temperature alarm
g_xPressAlarm : BOOL; // Pressure alarm
g_xFlowAlarm : BOOL; // Flow rate alarm
g_xLevelAlarm : BOOL; // Level alarm
// Timers
g_tCycleTime : TIME :=
T#100MS; // Control cycle time
g_tAlarmDelay : TIME :=
T#5S; // Alarm delay time
END_VAR""")
# Create a persistent Global Variable List
persistent_gvl = app.create_persistentvars("GVL_Settings")
# Define the persistent global variables
persistent_gvl.textual_declaration.replace("""VAR_GLOBAL PERSISTENT
// System Settings
p_xAutoStartEnabled : BOOL :=
TRUE; // Auto-start on power up
p_tStartupDelay : TIME :=
T#30S; // Startup delay time
// Control Parameters
p_rTempKp : REAL :=
1.5; // Temperature controller P gain
p_rTempKi : REAL :=
0.2; // Temperature controller I gain
p_rTempKd : REAL :=
0.1; // Temperature controller D gain
p_rPressKp : REAL :=
2.0; // Pressure controller P gain
p_rPressKi : REAL :=
0.3; // Pressure controller I gain
p_rPressKd : REAL :=
0.05; // Pressure controller D gain
p_rFlowKp : REAL :=
1.0; // Flow controller P gain
p_rFlowKi : REAL :=
0.15; // Flow controller I gain
p_rFlowKd : REAL :=
0.0; // Flow controller D gain
p_rLevelKp : REAL :=
3.0; // Level controller P gain
p_rLevelKi : REAL :=
0.25; // Level controller I gain
p_rLevelKd : REAL :=
0.1; // Level controller D gain
// Alarm Thresholds
p_rTempHighLimit : REAL :=
80.0; // Temperature high limit
p_rTempLowLimit : REAL :=
5.0; // Temperature low limit
p_rPressHighLimit : REAL :=
5.0; // Pressure high limit
p_rPressLowLimit : REAL :=
0.5; // Pressure low limit
p_rFlowHighLimit : REAL :=
200.0; // Flow high limit
p_rFlowLowLimit : REAL :=
10.0; // Flow low limit
p_rLevelHighLimit : REAL :=
90.0; // Level high limit
p_rLevelLowLimit : REAL :=
10.0; // Level low limit
END_VAR""")
# Create a constant Global Variable List
const_gvl = app.create_gvl("GVL_Constants")
# Define the constant global variables
const_gvl.textual_declaration.replace("""VAR_GLOBAL CONSTANT
// System Constants
c_iMaxDevices : INT :=
10; // Maximum number of devices
c_iMaxAlarms : INT :=
100; // Maximum number of alarms
// Physical Constants
c_rGravity : REAL :=
9.81; // Gravity acceleration (m/s²)
c_rWaterDensity : REAL :=
1000.0; // Water density (kg/mł)
c_rAirDensity : REAL :=
1.225; // Air density at sea level (kg/mł)
// Conversion Factors
c_rPa_To_Bar : REAL :=
0.00001; // Pascal to Bar conversion
c_rBar_To_PSI : REAL :=
14.5038; // Bar to PSI conversion
c_rLiter_To_M3 : REAL :=
0.001; // Liter to cubic meter conversion
// Time Constants
c_tMaxRunTime : TIME :=
T#24H; // Maximum continuous run time
c_tMaintenanceInterval : TIME :=
T#720H; // Maintenance interval (30 days)
END_VAR""")
print("Global Variable Lists created successfully!")
Tryb symulacji:
# set device to simulation mode -
this only check Simulation mark in the online tab
devs = proj.find('testdev') # type
here project name up to Application
devs[0].set_simulation_mode(True)
# alternatively check the sim is enabled beforehand and turn it on if not yet enabled
devs =
proj.find('testdev')
if
len(devs) >
0:
# check if sim is enabled
cur_sim_mode = devs[0].get_simulation_mode()
print(cur_sim_mode)
# enable sim conditionally
if not cur_sim_mode:
devs[0].set_simulation_mode(True)
Jeśli chcesz w pełni odkryć potencjał silnika skryptowego Python w CODESYS oraz dowiedzieć się, jak usprawnić automatyzację procesów dzięki wskazówkom Claude’a Sonneta, koniecznie zapoznaj się z częścią 2 tego artykułu. Znajdziesz tam informacje, jak zastosować zdobytą wiedzę w praktyce oraz wykorzystać zaawansowane możliwości tego narzędzia.