Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate Eplan pages with IO-modules importing from main.wago.plua #1417

Merged
merged 21 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion docs/user_manual/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
#### Настройки проекта
+ [Настройка диапазона IP-адресов проекта](#31-Настройка-диапазона-IP-адресов-проекта)
+ [Настройка тестирования проекта](#32-Настройка-тестирования-проекта)

+ [Импортирование старых проектов](#33-импортирование-старых-проектов)
+ [Как получить описание старого проекта](#331-как-получить-описание-старого-проекта)
+ [Как настроить правильную работу импорта проектов](#332-как-настроить-правильную-работу-импорта-проектов)
+ [Как импортировать описание старого проекта](#333-как-импортировать-описание-старого-проекта)
#### Оборудование IO
+ [Настройка узлов и модулей ввода-вывода](#41-Настройка-узлов-и-модулей-ввода-вывода)
+ [Привязка устройств к модулям IO](#42-Привязка-устройств-к-модулям-IO)
Expand Down Expand Up @@ -259,6 +262,56 @@ ProjectTestEnabled=True

Для корректного запуска тестов, тестовый скрипт должен быть обновлен до последней версии. Система пытается найти тестовый скрипт в директории `..\..\spec\main.lua`, относительно папки с файлами проекта. Также, помимо настроенного каталога с проектами, нужно чтобы скрипты управляющей программы тоже были настроены. Это каталог `..\..\sys-scripts` относительно папки с файлами проекта, также `..\..\editor` относительно папки с файлами проекта. Аргументы командной строки хранятся в папке `CMD` этого проекта.

### 3.3 Импортирование старых проектов ###

#### 3.3.1 Как получить описание старого проекта ####

Для импортирования проекта понадобится файл `main.wago.plua`. Чтобы получить данный файл, необходимо приложением `wprg4` открыть нужный проект с расширением `.ds4`, после чего экспортировать его: `Устройства` -> `Экспорт для WAGO 750-860` - как показано на рисунке ниже. После чего в папке с проектом появится нужный файл (`Внимание`: файл с описанием при экспорте заменяет старый файл описания другого проекта).

<p align="center"><img src="images/wprg4_export.png"></p>

<p align="center"><b>Рисунок</b> - <i>Экспорт проекта для WAGO</i></p>

#### 3.3.2 Как настроить правильную работу импорта проектов ####

Для корректной работы импорта описания старых проектов необходимо в файле конфигурации (`configuration.ini`) указать путь к EPLAN макросам модулей ввода-вывода, если такой настройки еще не установлено: необходимо в секции `[path]` добавить переменную `wago_macros_path = "ПУТЬ:\к\папке\с\макросами"`.

Сама папка с макросами должна быть структурирована в соответствие с последними изменениями в этой папке, а именно:
они должны быть разбиты по папкам соответствующим своим группам и именоваться по следующему формату `750-x00` (**x** - номер группы). Макрос выбирается по названию `WAGO.750-xyy.ema` (**xyy** - номер модуля).

Если у макроса есть какая-то модификация(вариация) типа `WAGO.750-xyy_025-000.ema`, то такой макрос выбран не будет, требуется строгое название макроса, который будет использоваться.


#### 3.3.3 Как импортировать описание старого проекта ####

Для импортирования описания старого проекта необходимо в меню выбрать следующую функцию: `EPlaner` -> `Импорт модулей ICP-CON проекта`.
В открывшемся окне проводника необходимо выбрать файл проекта `main.wago.plua`. После этого начнется импорт старого проекта.

Примечания по импорту проекта:
- В старых проектах использовались 4 типа узла:
+ 750-315 - RS-485
+ 750-815 - RS-485 (Programmable)
+ 750-341 - Ethernet coupler
+ 750-841 - Ethernet (Programmable)

Так как в текущих проектах нет описания первых двух узлов RS-485, то они заменяются на соответствующие Ethernet узлы

- Страницы в EPLAN генерируются с названиями по-умолчанию в соответствии с рисунком ниже:

<p align="center"><img src="images/imported_pages_explorer.png"></p>

<p align="center"><b>Рисунок</b> - <i>Структура импортированного проекта</i></p>

- В результате импорта узлов и модулей ввода вывода получаются страницы шин ПЛК и страницы с клеммами. Примеры можно увидеть на рисунках ниже:

<p align="center"><img src="images/import_plc_bus.png"></p>

<p align="center"><b>Рисунок</b> - <i>Пример сгенерированной страницы с шиной ПЛК</i></p>

<p align="center"><img src="images/import_clamps.png"></p>

<p align="center"><b>Рисунок</b> - <i>Сгенерированные страницы с клеммами</i></p>

## 4 Оборудование IO ##

**ВАЖНО:** Все устройства (устройства, узлы ввода-вывода и др.), добавляемые в проект должны быть расположены на ФСА (функциональная схема автоматизации) для того, что бы надстройка их считывала. Если устройства на ФСА нет, то оно не будет прочитано! Дополнительные поля устройств заполняются также на ФСА. Также __важно__, чтобы в устройстве на ФСА был включен флажок - "Главная функция", а в его макросах на других схемах - отключена.
Expand Down
Binary file added docs/user_manual/images/import_clamps.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user_manual/images/import_plc_bus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user_manual/images/wprg4_export.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions src/EasyEPlanner.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@
<Compile Include="EProjectManager\InsertMacrosInteraction.cs" />
<Compile Include="EProjectManager\SelectInteractionWhileEditModes.cs" />
<Compile Include="Extensions\ApiExtensions.cs" />
<Compile Include="ProjectImportICP\ImportModule.cs" />
<Compile Include="ProjectImportICP\ModulesImporter.cs" />
<Compile Include="InterprojectExchange\DeviceComparer.cs" />
<Compile Include="InterprojectExchange\DeviceInfo.cs" />
<Compile Include="InterprojectExchange\DeviceSignalsInfo.cs" />
Expand Down Expand Up @@ -216,6 +218,7 @@
<Compile Include="IO\IIOModule.cs" />
<Compile Include="IO\IIONode.cs" />
<Compile Include="IO\IOModuleInfo.cs" />
<Compile Include="Main\ImportIcpWagoModulesAction.cs" />
<Compile Include="Main\InterprojectExchangeAction.cs" />
<Compile Include="Configuration\ProjectHealthChecker.cs" />
<Compile Include="Device\DeviceManager.cs" />
Expand Down Expand Up @@ -467,6 +470,9 @@
<None Include="Lua\sys_shared_initializer.lua">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Lua\sys_wago_modules_importer.lua">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Resources\main.ico" />
</ItemGroup>
<ItemGroup>
Expand Down
5 changes: 4 additions & 1 deletion src/IO/IOManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,10 @@ private void InitIoModulesInfo()
if (!File.Exists(pathToFile))
NoFileErrorShow(templateName, pathToFile);

object[] result = lua.DoFile(pathToFile);
object[] result = lua.DoString(
new StreamReader(pathToFile, EncodingDetector.DetectFileEncoding(pathToFile), true)
.ReadToEnd());

if (result == null)
return;

Expand Down
20 changes: 20 additions & 0 deletions src/Lua/sys_wago_modules_importer.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
function Import(modulesImporter)
import_nodes_and_modules(modulesImporter)
Progress(100);
return 0;
end


function import_nodes_and_modules(importer)
if nodes == nil then
return
end

for node_index, node in ipairs(nodes) do
importer:ImportNode (node.ntype, node.address, node.IP or '')
for module_index, module in ipairs(node.modules or {}) do
importer:ImportModule(module[1], node_index, module_index)
Progress(100 / #nodes * (node_index - 1) + 100 / #nodes / #node.modules * (module_index - 1))
end
end
end
6 changes: 6 additions & 0 deletions src/Main/AddInModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ public bool OnInitGui()
"Генерация описания IOL-Conf", menuID, 1,
false, false);

menuID = oMenu.AddMenuItem(
"Импорт модулей ICP-CON проекта",
"ImportIcpWagoModules",
"Импорт модулей ICP-CON проекта", menuID, 1,
false, false);

menuID = oMenu.AddMenuItem(
"Обновления", nameof(OpenUpdater),
"", menuID, 1, true, false);
Expand Down
78 changes: 78 additions & 0 deletions src/Main/ImportIcpWagoModulesAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using EasyEPlanner.ProjectImportICP;
using Eplan.EplApi.ApplicationFramework;
using Eplan.EplApi.DataModel;
using Eplan.EplApi.DataModel.EObjects;
using Eplan.EplApi.DataModel.MasterData;
using LuaInterface;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace EasyEPlanner
{
[ExcludeFromCodeCoverage]
public class ImportIcpWagoModulesAction : IEplAction
{
~ImportIcpWagoModulesAction() { }

public bool Execute(ActionCallingContext oActionCallingContext)
{
try
{
Project currentProject = EProjectManager.GetInstance()
.GetCurrentPrj();
if (currentProject == null)
{
MessageBox.Show("Нет открытого проекта!", "EPlaner",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return true;
}

var openFileDialog = new OpenFileDialog
{
Title = "Открытие main.wago.plua",
Filter = "main.wago.plua|main.wago.plua",
Multiselect = false
};

if (openFileDialog.ShowDialog() == DialogResult.Cancel)
{
return true;
}

var data = new StreamReader(openFileDialog.FileName, EncodingDetector.DetectFileEncoding(openFileDialog.FileName), true).ReadToEnd();
// Fix main.wago.plua '}'
KirillGutyrchik marked this conversation as resolved.
Show resolved Hide resolved
data = Regex.Replace(data, @"}(?=(\r|\n|\r\n)\t+group_dev_ex)", "},", RegexOptions.None, TimeSpan.FromMilliseconds(100));
// Remove unnecessary lua-module
data = Regex.Replace(data, "require 'sys_wago'", "", RegexOptions.None, TimeSpan.FromMilliseconds(100));

var modulesImporter = new ModulesImporter(currentProject, data);
modulesImporter.Import();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

return true;
}

public bool OnRegister(ref string Name, ref int Ordinal)
{
Name = "ImportIcpWagoModules";
Ordinal = 30;

return true;
}

public void GetActionProperties(ref ActionProperties actionProperties)
{
}
}
}
81 changes: 81 additions & 0 deletions src/ProjectImportICP/ImportModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using Eplan.EplApi.DataModel.EObjects;
using IO;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EasyEPlanner.ProjectImportICP
{
/// <summary>
/// Описание импортированного модуля
/// </summary>
public interface IImportModule
{
/// <summary>
/// Адресное пространство по типу
/// </summary>
/// <param name="channelType">Тип канала</param>
int AddressSpace(string channelType);

/// <summary>
/// Описание модуля
/// </summary>
IOModuleInfo ModuleInfo { get; }
}

/// <summary>
/// Описание импортированного модуля (EPLAN-функции модуля и клемм, а также их адреса)
/// </summary>
[ExcludeFromCodeCoverage]
public class ImportModule : IImportModule
{
public ImportModule(PLC function, List<Terminal> clamps, IOModuleInfo moduleInfo)
{
foreach (var clamp in clamps)
{
string clampStr = clamp.Properties.FUNC_ADDITIONALIDENTIFYINGNAMEPART.ToString();

if (int.TryParse(clampStr, out int clampNumber))
{
int clampIndex = -1;


if (clampNumber < moduleInfo.ChannelAddressesIn.Count())
{
clampIndex = moduleInfo.ChannelAddressesIn[clampNumber];
}

if (clampNumber < moduleInfo.ChannelAddressesOut.Count())
{
clampIndex = moduleInfo.ChannelAddressesOut[clampNumber];
}

if (clampIndex >= 0)
this.clamps[clampIndex] = clamp;
}
}

this.function = function;
ModuleInfo = moduleInfo;

addressSpace["AO"] = ModuleInfo.AOCount;
addressSpace["AI"] = ModuleInfo.AICount;
addressSpace["DO"] = ModuleInfo.DOCount;
addressSpace["DI"] = ModuleInfo.DICount;
}

private readonly Dictionary<string, int> addressSpace = new Dictionary<string, int>();

private readonly PLC function;

private readonly Dictionary<int, Terminal> clamps = new Dictionary<int, Terminal>();

public IOModuleInfo ModuleInfo { get; private set; }

public int AddressSpace(string channelType)
=> addressSpace[channelType];
}
}
Loading