Managing the Engee model using a web application
In this demo, we will analyze the principles of implementing model management applications and compare two model management options using GenieFramework and Engee command management.
We will consider these aspects using the example of a sine wave generator model and tracking the signal output. We will set the "simulation time" parameter as "infinite".
The first option for managing such a model is to explicitly specify parameters from the Engee workspace.
Now let's look at the logic of the application itself in more detail. The logic and interface itself are presented in the app.jl file. This code creates an interactive web application using the GenieFramework framework and the StippleUI and PlotlyBase libraries for visualization. The application allows you to control the parameters of the sinusoidal signal through sliders and displays a graph in real time.
Block @app defines the data model:
@app begin
@in A = 1.0 # Signal amplitude (initial value 1.0)
@in Fs = 1.0 # Signal frequency (initial value 1.0)
@in P = 0.0 # Signal phase (initial value 0.0)
@out plotdata = [scatter(x=vec(T), y=vec(sin.(2π .* T)))] # Initial chart data
@out plotlayout = PlotlyBase.Layout( # Chart display settings
xaxis=attr(title="Time", showgrid=true),
yaxis=attr(title="Value", showgrid=true)
)
When we change the parameters A, Fs or P, we update the graph and transfer the data to the model, but as you can see, we do this not through the Engee workspace, but through the command set_param:
@onchange A, Fs, P begin
# Updating chart data with new parameters
plotdata = [scatter(x=vec(T), y=vec(A .* sin.(2π * Fs .* T .+ P)))]
# Sending parameters via Engee
engee.genie.send("A", A)
engee.genie.send("Fs", Fs)
engee.genie.send("P", P)
# Setting parameters in the SIN/Sin
engee.set_param module!("SIN/Sin",
"Amplitude" => Float64(A),
"Frequency" => Float64(Fs),
"Phase" => Float64(P))
end
end
Function ui() defines the structure of a web page:
function ui()
row([
column([ # Left column with controls
h6("Amplitude = {{A}}", style="margin-bottom: -10px"),
slider(0.1:0.20:10, :A, color="red", style="margin-bottom: 20px"),
h6("Frequency = {{Fs}}", style="margin-bottom: -10px"),
slider(0.1:0.20:10, :Fs, color="green", style="margin-bottom: 20px"),
h6("Phase = {{P}}", style="margin-bottom: -10px"),
slider(0.0:0.20:2π, :P, color="blue", style="margin-bottom: 20px")
], style="width: 40%; padding: 20px;"),
column([ # Right column with graph
plot(:plotdata, layout=:plotlayout)
], style="width: 60%; padding: 20px; background-color: #f9f9f9; border-radius: 10px;")
])
end
Creating a route for the home page:
@page("/", ui, debounce=1)
Next, we will run our application using GenieFramework.
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")
The application can be opened either by clicking on the link or by launching it inside. ngscript.
# display(
# MIME("text/html"),
# """<iframe
# src="$app_url"
# width="750" height="500"
# style="border: none;">
# </iframe>"""
# )
The figure below shows the behavior of the model under the control of a web application.
You can turn off the application using the following command:
# engee.genie.stop(string(@__DIR__,"/app.jl"))
Conclusion
In this example, two ways of managing models using GenieFramework were shown at once, and the possibilities of using team management to implement larger projects in this area were demonstrated.