module Window_SA

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

	for inner fmu Window window
		at "./path/to/Window.fmu"
		with input ports displacement (rad), speed (rad/s), reaction_force (N)
		with output ports height (m), reaction_torque (N.m)

/*
In the original version, no input ports where declared, so all dangling inputs of the original fmus are bound to the input ports of the adapted FMU.
In the canonical version, the input and output ports are all declared explicitly, and their bindings are implemented in the in/out rules.
*/

input ports 	reaction_force,
				displacement,
				speed

output ports	disp,
				tau


control rules {
	do_step(window, t, H); // includes update_in rules and update_out (update-in rules do not update state)
	return H;
}

in var 	stored_windowsa_reaction_force := 0.0, 
		stored_windowsa_displacement := 0.0, 
		stored_windowsa_speed := 0.0;

in rules {
	true -> {
		/*
		is_set checks whether the input value is given in the setValues call of the adapted FMU.
		Notice that in the canonical version, all ports are prefixed.
		*/
		if (is_set(windowSA.reaction_force)){
			stored_windowsa_reaction_force := windowSA.reaction_force;
		}
		if (is_set(windowSA.displacement)){
			stored_windowsa_displacement := windowSA.displacement;			
		}
		if (is_set(windowSA.speed)){
			stored_windowsa_speed := windowSA.speed;
		}
	} --> {
		window.reaction_force := stored_windowsa_reaction_force;
		window.displacement := stored_windowsa_displacement; 
		window.speed := stored_windowsa_speed;
	};
}

out var stored_window_reaction_torque := 0,
		stored_window_height := 0;
		
out rules {
	true -> {
		stored_window_reaction_torque := window.reaction_torque;
		stored_window_height := window.height;
	} --> {
		windowSA.tau := - stored_window_reaction_torque;
		windowSA.disp := stored_window_height / 100;
	};
}

