AnyMath 文档
Notebook

在Engee中创建和连接用户设备

导言

此示例讨论创建您自己的自定义设备支持包,以便通过使用Engee在Engee中工作。整合。
这种方法允许您扩展环境的标准功能,并连接用Python编写的自定义逻辑。

根据说明,用户设备将准备好:

-通过扩展机制连接到Engee;
-提供自己的方法;
-可以从脚本中调用并在模型中使用;
-它在Engee方案中用作用户定义的功能块。

这种方法适用于有必要的任务:

-实现非标准设备逻辑;
-启用外部计算;
-添加读取、写入和处理数据的方法;
-组织Python和Engee之间自己的接口。


什么是用户设备?

[自定义支持包устройств](https://engee.com/helpcenter/stable/ru/engee-hardware/engee-integrations-custom-packages.html )在Engee中是一个可扩展的对象,被描述为Python类,并通过[Engee.Integrations]连接(https://engee.com/helpcenter/stable/ru/engee-hardware/engee-integrations.html )。

这样的类必须与Engee设备管理器的基础结构兼容,并从基类继承。:

BaseDevice

Это дает возможность:

  • регистрировать устройство в Engee;
  • автоматически обнаруживать его методы;
  • вызывать пользовательские функции из среды;
  • использовать устройство как источник логики в модели.

Общая структура пакета поддержки

Пакет поддержки состоит из нескольких уровней:

  1. Пользовательское устройство
    Описывает конкретную логику устройства и его методы.

  2. Python-модуль на компьютере пользователя
    Содержит реализацию класса устройства и его функций.

  3. Интеграционный слой Engee
    Обеспечивает подключение Python-модуля и взаимодействие между Engee и пользовательским кодом.

С практической точки зрения это означает следующее:

  • пользователь создает папку устройства;
  • внутри размещает Python-файл с реализацией класса;
  • затем загружает расширение в Engee;
  • после этого может создавать экземпляры устройства и вызывать его методы.

设备类要求

用户设备必须实现为继承自 BaseDevice.

通常,这样的类定义:

*构造函数:

__init__()
  • деструктор:

    __del__()
    
  • один или несколько пользовательских методов:

    custom_method_1()
    custom_method_2()
    ...
    custom_method_N()
    

Именно эти методы затем становятся доступны для вызова из Engee.


Подготовка и структура каталогов

1. Создание каталога расширения

Для начала необходимо подготовить папку расширения, внутри которой будут размещаться пользовательские устройства.

Самый минимальный пример структуры каталогов:

D:\dev_devices\extension\
──装置\
    ──文件\
        ──tofile.py

Где:

  • extension — корневая папка пакета поддержки;
  • devices — каталог пользовательских устройств;
  • tofile — папка конкретного устройства;
  • tofile.py — Python-файл с реализацией класса устройства.

Названия каталогов можно выбирать свои, но их лучше делать короткими и понятными.


Создание Python-класса устройства

2. Базовая реализация пользовательского устройства

Внутри файла tofile.py необходимо создать класс, наследуемый от BaseDevice.

Пример базовой заготовки:

从设备。base_device导入BaseDevice

类Tofile(BaseDevice):
    def__init__(self)->无:
        通行证

    def__del__(self)->无:
        通行证

这种最小的结构已经允许Engee将用户类检测为设备。


3. 添加自定义方法

创建类后,您需要定义应该从Engee调用的方法。

您可以实现自定义功能,例如:

*获取效用函数的结果;
*表达式的计算;
*获得主人的时间;
*将值写入文件。

下面是一个具有多个方法的类的典型版本。

从设备。base_device导入BaseDevice
进口时间

类Tofile(BaseDevice):
    def__init__(self)->无:
        通行证

    def__del__(self)->无:
        通行证

    def solve_equation(self,x:float,y:float,z:float)->float:
        返回x*y-z

    def get_host_time(self)->str:
        host_time=时间。本地时间()
        返回str(host_time)

4. Реализация метода записи числа в файл

Одной из практичных функций пользовательского устройства для моделирования является запись данных в файл.

Для этого можно добавить метод следующего вида:

从设备。base_device导入BaseDevice

类Tofile(BaseDevice):
    def__init__(self)->无:
        通行证

    def__del__(self)->无:
        通行证

    def write_number(self,file_path:str,number:float)->str:
        试试:
            用open(file_path,'a',encoding='utf-8')作为f:
                f.write(f"{number}\n")
            返回"确定"
        例外情况为e:
            返回f"{e}"

Что делает этот метод

Метод write_number(...):

  • принимает путь к файлу;
  • принимает число;
  • открывает файл в режиме добавления;
  • записывает значение в новую строку;
  • возвращает строковый результат выполнения.

Это удобный шаблон для простого обмена данными между моделью Engee и локальной файловой системой.


在Engee中连接支持包

5. 创建连接脚本

准备好Python模块后,您需要将扩展连接到Engee。

为此,将导入服务命名空间并加载扩展。

In [ ]:
using Main.EngeeDeviceManager.Devices.UTILS
using Main.EngeeDeviceManager.UTILS_API
In [ ]:
module_path = "D:\\dev_devices\\extension";
utils = UTILS.Utils()
UTILS_API.loadExtension(utils, module_path)

这个代码是做什么的?

module_path="D:\\dev_devices\\extension";

Задает путь к корневой папке пакета поддержки.

utils=UTILS。Utils()

Создает вспомогательный объект, необходимый для загрузки расширения.

UTILS_API。loadExtension(utils,module_path)

Подключает пользовательский пакет поддержки к Engee.

После успешного выполнения этой команды пользовательское устройство становится доступным для использования в среде.

6. Перезапуск менеджера устройств Engee

После загрузки расширения рекомендуется перезапустить или повторно инициализировать соответствующий компонент Engee, чтобы среда заново обнаружила новые устройства.

Для этого используется команда:

In [ ]:
engee.package.start("Engee-Device-Manager")

Проверка успешного подключения

7. Открытие окна состояния подключения

После загрузки расширения необходимо проверить, что Engee успешно обнаружил пользовательское устройство.

Признаками успешного подключения являются сообщения следующего типа:

  • соединение с сервером установлено;
  • класс найден;
  • класс наследуется от BaseDevice;
  • методы класса обнаружены;
  • типы аргументов и возвращаемых значений корректно распознаны;
  • расширение успешно загружено.

在日志中检查什么是重要的

下载扩展后,您需要确保Engee已正确识别:

image.png

设备类,例如:

找到的类:Tofile,继承自BaseDevice

Методы устройства, например:

方法:write_number
方法:__init__
方法:__del__

Аргументы метода, например:

参数:file_path类型:str
参数:数字类型:浮点数

Возвращаемый тип, например:

返回值:str

Если эти данные отображаются корректно, значит пакет поддержки загружен правильно и устройство готово к использованию.


Использование устройства в скрипте Engee

8. Создание экземпляра пользовательского устройства

После загрузки расширения можно создать экземпляр пользовательского класса.

Пример:

In [ ]:
myfile = TOFILE.Tofile()

Здесь:

  • myfile — экземпляр пользовательского класса;
  • TOFILE — пространство или модуль пользовательского устройства;
  • Tofile() — конструктор класса.

После выполнения этой команды создается рабочий экземпляр устройства, методы которого можно вызывать из Engee.


9. 调用自定义方法

创建实例后,可以直接调用设备方法。

例如:

In [ ]:
myfile.write_number("D:\\dev_devices\\extension\\test.txt", 3.1415)

执行后,一个数字将被写入指定的文件。 3.1415.


在模型中使用用户设备

10. 创建自定义支持包块

成功连接设备后,您可以在Engee模型中使用它。
为此,请将以下代码添加到Engee功能块:

package_dir="/internal_persistent_vol/support_packages/locations/Engee-Device-Manager/EngeeDeviceManager。jl"

include("$(package_dir)/src/EngeeDeviceManager.jl")


使用。工程管理者
使用。工程师。装置。文件/文件

结构块<:AbstractCausalComponent
    myfile::TOFILE。文件/文件
    功能块()
      myfile=TOFILE。文件()
      新文件(myfile)
    结束
结束

函数(c::块)(t::实数)
  我的文件。write_number(路径,数字)
结束

功能终止!(c::座)
  什么也不退货
结束

number - значение, которые мы будем получать из входного порта

path - параметр, получаемый из маски блока.

Модель примера будет выглядеть следующим образом:

image.png

В маске блока укажем путь файла, в который будут записаны значения из модели.

11. Результаты выполнения модели

在指定的PC目录中启动模型后,我们将收到文件test1。具有正弦值的txt。 该文件可以在脚本中下载和分析。:

In [ ]:
function TxtToVec(Path::String)
    txt = open(io->read(io, String), Path);
    data_str = "[" * replace(txt, "\n" => ",") * "]";
    return eval(Meta.parse(data_str))
end

txt_content = TxtToVec("$(@__DIR__)/test1.txt");

gr(format=:png)
plot(txt_content)
Out[0]:
No description has been provided for this image

从文件的值的图形是明确的正弦性质与指定的参数,因此,所有必要的数据被写入文件。 现在,自定义支持包块可以包含在自定义块库中,例如tofile。nglib。

实用建议

1. 遵循简单的类结构

最好从最小的集合开始。:

  • __init__
  • __del__
    *1-2自定义方法

检查功能后,您可以逐步扩展功能。


2. 显式指定参数的类型

必须指定输入参数的类型和返回值,例如:

def write_number(self,file_path:str,number:float)->str:
```</span>

这提供了Python中的包方法和Engee中的Julia接口之间的数据类型定义。

---

3. 处理异常

如果该方法与文件、外部资源或计算交互,则添加 try/except 使错误不会导致紧急停机。


4. 从简单的测试开始。

在集成到模型之前,首先检查很方便:

*创建类的实例;
*调用方法;
*返回值。

并且仅随后将设备连接到操作电路。


结论

遵循此指令后,将创建Engee的自定义设备,在Python中实现并通过Engee连接。整合。

完成的设置允许您:

*创建自定义设备类;
*添加自定义方法;
*将Python逻辑连接到Engee;
*在方案和模型中使用扩展;
*将非标准功能集成到工作流中。

这种机制是方便使用作为基础:

*文件共享;
*外部计算;
*与设备的互动;
*与自定义库集成;
*实现专门的应用程序逻辑。