Managing duplicate stations with MappView

Hi

we often have duplicate stations in our projects, means two Task and one is referenced to the other.

Both have the same variable structure, see below “gSLF_02” and “gSLF_06” as an example. In an INIT file we assign the correct structure to the corresponding station.

My question is now, how can I handle that with my mappview visualisation? Because I dont want to have to build up all the content twice there…

I made a third globale variable with the same structure as the two station have. Now in dependence of the active Page (PageID is written in a variable), I ACCESS gSLF_02 or gSLF_06. This is done in the code, not in the visualisation.

All bindings in the mappview projects are done to the gSLF variable, so the values are switching correct, if I switch the page.

Now I have to problems:

  • HOw can I switch easily the text on the page (for example a name of an axis) in dependence of the active page?
  • If there would be a second client connected to the CPU, then his variables will switch to as soon as I change the ACCESS. So maybe he is on Page of SLF_02 and somebody switches on the other panel to Page SLF_06 - then his variables will also switch ACCESS to gSLF_06 even he is still on Page SLF_02 though

Or do you have any other ideas how to handle duplicated Stations/Task with mappView?

1 Like

Your use case is really specific, and I’m not sure if there is an easy solution for that. From experience, when I had the same stations, I did not use a structure variable with an index but instead used a structured array.

Example: gSLF_01 = gSLF[1] ; gSLF_02 = gSLF[2], etc.

This made my logic:

  • Easy to expand if I had more same stations
  • If the logic for all stations was the same, I had the code only once, and each change was automatically applied to all stations
  • For mapView, you could use list binding,

Just another view on your point.

Thanks for the tip.

  • in our solution, we do have the logic of the stations only once too
  • how would you solve the problem with to clients connected to the MappView visualisation?

Hi Stefan,

I didn’t know if I correctly understand your needs, but I have maybe a solution for you.

So in a mappView application we had 6 clients possible. I will take as example the manual mode of axis. We defined a constant variable “MAX_MAPPVIEW_SESSIONS” to 5

We had a function block to handle automatic and manual command on axis we can name it “FB_Axis”.

All the “FB_Axis” are in an array and the index of the array is the number of the axis.

Now I a mappView task we created multiple pointers and a variable to handle current ID per client like this:

VAR
	WidgetPilotAxisAdrSelected : ARRAY[0..MAX_MAPPVIEW_SESSIONS] OF UDINT;
END_VAR
(*Pointers to component per client MappView*)
VAR
	pWidgetPilotAX_c0 : REFERENCE TO FB_Axis;
	pWidgetPilotAX_c1 : REFERENCE TO FB_Axis;
	pWidgetPilotAX_c2 : REFERENCE TO FB_Axis;
	pWidgetPilotAX_c3 : REFERENCE TO FB_Axis;
	pWidgetPilotAX_c4 : REFERENCE TO FB_Axis;
	pWidgetPilotAX_c5 : REFERENCE TO FB_Axis;
END_VAR
(*Navigation*)
VAR
	AxisSelected : ARRAY[0..MAX_MAPPVIEW_SESSIONS] OF STRING[3];
END_VAR

Our “AxisSelected” variable in a string because it come from a listBox.

So we create a session variable “sAxisselectedString” that store this current index of the axis when you click on the listBox.

This session variable is bind to “AxisSelected” using a list binding on the slotId:

<!-- selected list value -->
<Binding mode="twoWay">
	<Source xsi:type="listElement">
		<Selector xsi:type="session" refId="::SYSTEM:clientInfo.slotId" attribute="value" />
		<be:List xsi:type="be:opcUa" attribute="value">
			<bt:Element index="0" refId="::MappView:AxisSelected[0]" />
			<bt:Element index="1" refId="::MappView:AxisSelected[1]" />
			<bt:Element index="2" refId="::MappView:AxisSelected[2]" />
			<bt:Element index="3" refId="::MappView:AxisSelected[3]" />
			<bt:Element index="4" refId="::MappView:AxisSelected[4]" />
			<bt:Element index="5" refId="::MappView:AxisSelected[5]" />
		</be:List>
	</Source>
	<Target xsi:type="session" refId="sAxisselectedString" attribute="value" />
</Binding>

Now you know for each client connected which axis they are seeing.

In structured text we do this:

FOR i:=0 TO MAX_MAPPVIEW_SESSIONS DO
	// Widget Axis manual commands
	WidgetPilotAxisAdrSelected[i]	:= ADR(gAxisList[STRING_TO_INT(AxisSelected[i])]);	
	CASE i OF
		0:	pWidgetPilotAX_c0 ACCESS WidgetPilotAxisAdrSelected[i];
		1:	pWidgetPilotAX_c1 ACCESS WidgetPilotAxisAdrSelected[i];
		2:	pWidgetPilotAX_c2 ACCESS WidgetPilotAxisAdrSelected[i];
		3:	pWidgetPilotAX_c3 ACCESS WidgetPilotAxisAdrSelected[i];
		4:	pWidgetPilotAX_c4 ACCESS WidgetPilotAxisAdrSelected[i];
		5:	pWidgetPilotAX_c5 ACCESS WidgetPilotAxisAdrSelected[i];
	END_CASE;
END_FOR;

Like this you get the pointer of each client axis on 6 separate variables.

Now to bind axis manual commands to the mappView, we created compound widget for axis manual command taking as input binding a “StructureBindableProperty” based on the function block “FB_Axis”.
Then like this you map whatever you want it the compound widget.

So now we declare our pointers to OpcUa server. And we binding it to our compound widget like this:

<!-- Pointers to function blocks of AxisManagement -->
<Binding mode="twoWay">
	<Source xsi:type="listElement">
		<Selector xsi:type="session" refId="::SYSTEM:clientInfo.slotId" attribute="value" />
		<be:List xmlns:be="http://www.br-automation.com/iat2015/bindingListEmbedded/engineering/v2" xsi:type="be:opcUa" attribute="value">				
			<bt:Element index="0" refId="::MappView:pWidgetPilotAX_c0" />
			<bt:Element index="1" refId="::MappView:pWidgetPilotAX_c1" />
			<bt:Element index="2" refId="::MappView:pWidgetPilotAX_c2" />
			<bt:Element index="3" refId="::MappView:pWidgetPilotAX_c3" />
			<bt:Element index="4" refId="::MappView:pWidgetPilotAX_c4" />
			<bt:Element index="5" refId="::MappView:pWidgetPilotAX_c5" />
		</be:List>
	</Source>
	<Target xsi:type="brease" widgetRefId="compoundwidget_PilotingAX" contentRefId="ContentAxis" attribute="pAxisManagement" />
</Binding>

So if you need to add more client it’s not a big deal to adjust the application:

  • You increase the CONSTANT
  • You create a new pointer and add it to the case in Structured Text
  • You add new index in both bindings

Hope it can help you to solve your problem.

Regards,
Florent

3 Likes

using slotID and list binding..you have got very nice explanation from @florent.boissadier

1 Like