Документация Engee
Notebook

Управление моделью Engee при помощи веб-приложения

В данной демонстрации мы проанализируем принципы реализации приложений управления моделями и сравним два варианта управления моделями – при помощи GenieFramework и командного управления Engee.

Эти аспекты мы рассмотрим на примере модели генератора синусоиды и отслеживания выхода сигнала. Параметр «время симуляции» установим как «бесконечное».

image.png

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

image.png

Теперь разберём логику самого приложения более подробно. Сама логика и интерфейс представлены в файле app.jl. Этот код создает интерактивное веб-приложение с использованием фреймворка GenieFramework и библиотек StippleUI и PlotlyBase для визуализации. Приложение позволяет управлять параметрами синусоидального сигнала через слайдеры и отображает график в реальном времени.

Блок @app определяет модель данных:

@app begin
    @in A = 1.0      # Амплитуда сигнала (начальное значение 1.0)
    @in Fs = 1.0     # Частота сигнала (начальное значение 1.0)
    @in P = 0.0      # Фаза сигнала (начальное значение 0.0)
    
    @out plotdata = [scatter(x=vec(T), y=vec(sin.(2π .* T)))]  # Начальные данные графика
    @out plotlayout = PlotlyBase.Layout(  # Настройки отображения графика
        xaxis=attr(title="Время", showgrid=true),
        yaxis=attr(title="Значение", showgrid=true)
    )

При изменении параметров A, Fs или P мы обновляем график и передаём данные в модель, но, как вы можете заметить, делаем это уже не через рабочую область Engee, а через команду set_param:

    @onchange A, Fs, P begin
        # Обновление данных графика с новыми параметрами
        plotdata = [scatter(x=vec(T), y=vec(A .* sin.(2π * Fs .* T .+ P)))]
        
        # Отправка параметров через Engee
        engee.genie.send("A", A)
        engee.genie.send("Fs", Fs)
        engee.genie.send("P", P)
        
        # Установка параметров в модуль SIN/Sin
        engee.set_param!("SIN/Sin",
                 "Amplitude" => Float64(A),
                 "Frequency" => Float64(Fs),
                 "Phase" => Float64(P))
    end
end

Функция ui() определяет структуру веб-страницы:

function ui()
    row([
        column([  # Левая колонка с элементами управления
            h6("Амплитуда = {{A}}", style="margin-bottom: -10px"),
            slider(0.1:0.20:10, :A, color="red", style="margin-bottom: 20px"),
            
            h6("Частота = {{Fs}}", style="margin-bottom: -10px"),
            slider(0.1:0.20:10, :Fs, color="green", style="margin-bottom: 20px"),
            
            h6("Фаза = {{P}}", style="margin-bottom: -10px"),
            slider(0.0:0.20:2π, :P, color="blue", style="margin-bottom: 20px")
            ], style="width: 40%; padding: 20px;"),
            
        column([  # Правая колонка с графиком
            plot(:plotdata, layout=:plotlayout)
        ], style="width: 60%; padding: 20px; background-color: #f9f9f9; border-radius: 10px;")
    ])
end

Создание маршрута для главной страницы:

@page("/", ui, debounce=1)

Далее выполним запуск нашего приложения при помощи GenieFramework.

In [ ]:
app_url = string(engee.genie.start(string(@__DIR__,"/app.jl")))
app_url = replace((match(r"https?://[^\s\\]+", app_url)).match, r"\e$" => "") 
println("URL: $app_url")
URL: https://engee.com/prod/user/demo54365636-yurev/genie/genieframework_and_model/

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

In [ ]:
# display(
#         MIME("text/html"), 
#         """<iframe 
#                 src="$app_url" 
#                 width="750" height="500" 
#                 style="border: none;">
#         </iframe>"""
#         )

image_2.png

На рисунке ниже показано поведение модели под управлением веб-приложения.

zapis_2025_06_05_174535.gif

Выключить приложение можно при помощи следующей команды:

In [ ]:
# engee.genie.stop(string(@__DIR__,"/app.jl"))

Вывод

В этом примере было показано сразу два способа управления моделями при помощи GenieFramework, а также продемонстрированы возможности применения командного управления для реализации более крупных проектов в этом направлении.

Блоки, использованные в примере