module Window_SA

semantic adaptation reactive mealy WindowSA windowSA
at "./path/to/WindowSA.fmu"

/*
Reactive means that the unit expects the following treatment:
Supose the external master is at time t, and that there is an FMU f providing inputs to windowsa.
Then,
f.doStep(t, H) // f goes from t->t+H 
u := f.getValues(...)
windowsa.setValues(u) // Input provided from the future (t+H)
windowsa.doStep(t, H) // windowsa goes from t->t+H
v := windowsa.getValues(...)

Delayed unit means that the unit expects the following treatment:
Supose the external master is at time t, and that there is an FMU f providing inputs to windowsa.
Then,
pu := f.getValues(...)
f.doStep(t, H) // f goes from t->t+H 
windowsa.setValues(pu) // Input provided at the time t
windowsa.doStep(t, H) // windowsa goes from t->t+H and does not need input at time (t+H)
v := windowsa.getValues(...)


Mealy unit means the following:
windowsa.setValues(v1)  // values set at time t
o1 = windowsa.getValues() // values set at time t
assert v2 <> v1 // Assumption
windowsa.setValues(v2)  // values set at time t
o2 = windowsa.getValues() // values set at time t
It is probably the case that o1 <> o2

Moore unit means the following:
windowsa.setValues(v1)  // values set at time t
o1 = windowsa.getValues() // values set at time t
assert v2 <> v1 // Assumption
windowsa.setValues(v2)  // values set at time t
o2 = windowsa.getValues() // values set at time t
It must be the case that o1 == o2
In other words, the output at time t, only depends on the state at time t.
*/

	
	/*
	The definition for the wrapped FMU is now done here.
	This is because, for adaptations that wrap multiple FMUs as well as other adaptations, the connection information cannot be fully completed in the senario description (see the window_obstacle.sa example).
	*/
	for inner fmu Window window
		at "./path/to/WindowSA.fmu"
		with input ports displacement (rad), speed (rad/s), reaction_force (N)
		with output ports height (cm), reaction_torque (N.m)

/*
No need to have input ports declared for this model.
Every input port of the original FMU will be automatically assumed to be an input port of the adapted FMU.

If there is an input port window.p which is dangling, but is not declared here, then an input port windowsa.p will be created in the adapted FMU, and we will have that window.p -> windowsa.p.
*/

/*
Declares two output ports, and specified how height is mapped to disp.
Here, the units need to be specified, so that the conversion can take place.
The units of disp can be either obtained from the scenario, or specified explicitly here.
*/
output ports disp (m)  <- height, tau
/*
There are alternative ways that this can be interpreted:
disp  := arbitrary_function(height) * 100 or arbitrary_function(height * 100) (they are not necessarily equal)
We pick the first one, so what we have is this:
aux_var := arbitrary_function(height);
disp := aux_var*100; // This part never has to be coded.
*/

out rules {
	true -> {} --> {
		tau := -reaction_force;
	};
}