[Compound Widget] Increase value with 1 when pressing a button

With event bindings it is easy to increase an OPCua value with 1 when pressing a button, i have build that like this:

 <EventBinding id="ContentXYZ_Jog.pbSpeedDown.Click">
      <Source xsi:type="widgets.brease.MomentaryPushButton.Event" contentRefId="ContentXYZ_Jog" widgetRefId="pbSpeedDown" event="Click" />
      <Operand datatype="ANY_REAL" name="ManualSpeed">
        <ReadTarget xsi:type="opcUa.NodeAction.Read" refId="::XYZ_Inf_Pr:XYZ_Inf.Hmi.JogPanel.SetManualSpeed.Value">
          <Method xsi:type="opcUa.NodeAction.GetValue" />
        </ReadTarget>
      </Operand>
      <Operand datatype="ANY_REAL" name="ManualSpeedMin">
        <ReadTarget xsi:type="opcUa.NodeAction.Read" refId="::XYZ_Inf_Pr:XYZ_Inf.Hmi.JogPanel.SetManualSpeed.Min">
          <Method xsi:type="opcUa.NodeAction.GetValue" />
        </ReadTarget>
      </Operand>
      <EventHandler condition="ManualSpeed&gt;ManualSpeedMin">
        <Action>
          <Target xsi:type="opcUa.NodeAction" refId="::XYZ_Inf_Pr:XYZ_Inf.Hmi.JogPanel.SetManualSpeed.Value">
            <Method xsi:type="opcUa.NodeAction.AddValue" value="-1" />
          </Target>
        </Action>
      </EventHandler>
    </EventBinding>

Now I want to build the same functionality into an compound widget, so inside the EventBindings section of a compound widget.

I have searched the help and found the below code, but in all cases this only work to set a static value, in this case with the value 15. But I want to increase the value of niSpeed with 1.

Tryout 1:

<EventBinding id="IncreaseSpeed5">
			<Source xsi:type="widget.Event" widgetRefId="pbSpeedUp" event="Click" />
			<EventHandler condition="">
				<Action>
					<ReadTarget xsi:type="widget.Action.Read" widgetRefId="niSpeed">	 
						<Method name="GetValue"/>
					</ReadTarget>
					<Result>
						<ResultHandler condition="result=1">
							<Action>
								<Target xsi:type="widget.Action" widgetRefId="niSpeed">
									<Method name="SetValue" value="15" />
								</Target>
							</Action>
						</ResultHandler>
					</Result>
				</Action>
			</EventHandler> 
		</EventBinding>

Tryout 2:

		<EventBinding id="IncreaseSpeed4">
			<Source xsi:type="widget.Event" widgetRefId="pbSpeedUp" event="Click" />
			<Operand name="ManualSpeed" datatype="ANY_REAL">
				<ReadTarget xsi:type="widget.Action.Read" widgetRefId="niSpeed">	 
					<Method name="GetValue"/>
				</ReadTarget>
			</Operand>
			<Operand name="ManualSpeedMax" datatype="ANY_REAL">
				<ReadTarget xsi:type="widget.Action.Read" widgetRefId="niSpeedMax">	 
					<Method name="GetValue"/>
				</ReadTarget>
			</Operand>
			<EventHandler condition="ManualSpeed&lt;ManualSpeedMax">
				<Action>
					<ReadTarget xsi:type="widget.Action.Read" widgetRefId="niSpeed">	 
						<Method name="GetValue"/>
					</ReadTarget>
					<Result>
						<ResultHandler>
							<Action>
								<Target xsi:type="widget.Action" widgetRefId="niSpeed">
									<Method name="SetValue" value="15" />
								</Target>
							</Action>
						</ResultHandler>
					</Result>
				</Action>
			</EventHandler> 
		</EventBinding>

I have tried this, but that does not work:

		<EventBinding id="IncreaseSpeed5">
			<Source xsi:type="widget.Event" widgetRefId="pbSpeedUp" event="Click" />
			<EventHandler condition="">
				<Action>
					<ReadTarget xsi:type="widget.Action.Read" widgetRefId="niSpeed">	 
						<Method name="GetValue"/>
					</ReadTarget>
					<Result>
						<ResultHandler condition="result=1">
							<Action>
								<Target xsi:type="widget.Action" widgetRefId="niSpeed">
									<Method name="SetValue" value="result+1" />
								</Target>
							</Action>
						</ResultHandler>
					</Result>
				</Action>
			</EventHandler> 
		</EventBinding>

I’m out of clues. Does anybody has a solution.

Hello @c590729 Rens welcome to the B&R Community.

I must say you are really close to a solution and I’m sure you will say the same if you see how I accomplished this inside a compound widget.

First the result with both buttons and the numeric input inside a compound widget:

2024-06-05_17-22-47

Now the solution inside the compound widget:

    <Widgets>
		<Widget xsi:type="widgets.brease.Button" id="ButtonMinus" top="10" left="10" zIndex="5" text="Button -" />
		<Widget xsi:type="widgets.brease.Button" id="ButtonPlus" top="10" left="310" zIndex="4" text="Button +" />
		<Widget xsi:type="widgets.brease.NumericInput" id="NumericInput1" top="10" left="160" zIndex="6" />
	</Widgets>
	<Properties>
		<Property xsi:type="BindableProperty" name="Test" type="Number" defaultValue="0" readOnly="false" category="Data" >
			<Description>Description will be shown in property grid.</Description>
			<Mappings>
				<Mapping widget="NumericInput1" property="value" mode="twoWay"/>
			</Mappings>
		</Property>
	</Properties>

Eventbinding:

    <EventBindings>
		
		<EventBinding id="ButtonPlusClicked">
			<Source xsi:type="widget.Event" widgetRefId="ButtonPlus" event="Click" />
			<Operand name="CurrentValue" datatype="ANY_INT">
				<ReadTarget xsi:type="widget.Action.Read" widgetRefId="NumericInput1">	 
					<Method name="GetValue"/>
				</ReadTarget>
			</Operand>
			<EventHandler>
				<Action>															
					<Target xsi:type="widget.Action" widgetRefId="NumericInput1">
						<Method name="SetValue" value="=CurrentValue+1" />
					</Target>												
				</Action>	
			</EventHandler>
		</EventBinding>	
		
		<EventBinding id="ButtonMinusClicked">
			<Source xsi:type="widget.Event" widgetRefId="ButtonMinus" event="Click" />
			<Operand name="CurrentValue" datatype="ANY_INT">
				<ReadTarget xsi:type="widget.Action.Read" widgetRefId="NumericInput1">	 
					<Method name="GetValue"/>
				</ReadTarget>
			</Operand>
			<EventHandler>
				<Action>															
					<Target xsi:type="widget.Action" widgetRefId="NumericInput1">
						<Method name="SetValue" value="=CurrentValue-1" />
					</Target>												
				</Action>	
			</EventHandler>
		</EventBinding>	

	</EventBindings>

You can see I’m just using an Operand for reading the current value of the numeric input which is tied to the OpcUa variable.

In the Action I’m doing pretty much the same as you tried setting the value of the numeric input to =Operand+1 or =Operand-1.

I realize there may be some additional details in your application that I did not consider or a slightly different use case but if that’s the case let’s discuss!

Something just occurred to me. If you don’t need/want the actual numeric display on the compound widget you can simply set the visibility = false to make it a hidden widget.

6 Likes

The solution was indeed not far away. You sir, are brilliant, thanks! That works like a charm!

The main issue was that I forget to add the ‘value="=’ in the code, so this also works:

		<EventBinding id="IncreaseSpeed5">
			<Source xsi:type="widget.Event" widgetRefId="pbSpeedUp" event="Click" />
			<EventHandler condition="">
				<Action>
					<ReadTarget xsi:type="widget.Action.Read" widgetRefId="niSpeed">	 
						<Method name="GetValue"/>
					</ReadTarget>
					<Result>
						<ResultHandler condition="">
							<Action>
								<Target xsi:type="widget.Action" widgetRefId="niSpeed">
									<Method name="SetValue" value="=result+1" />
								</Target>
							</Action>
						</ResultHandler>
					</Result>
				</Action>
			</EventHandler> 
		</EventBinding>

But to conclude this matter, the final code can be found below. This code also takes the min / max values into account:

		<!-- Increase Speed -->
		<EventBinding id="IncreaseSpeed">
			<Source xsi:type="widget.Event" widgetRefId="pbSpeedUp" event="Click" />
			<Operand name="ManualSpeed" datatype="ANY_REAL">
				<ReadTarget xsi:type="widget.Action.Read" widgetRefId="niSpeed">	 
					<Method name="GetValue"/>
				</ReadTarget>
			</Operand>
			<Operand name="ManualSpeedMax" datatype="ANY_REAL">
				<ReadTarget xsi:type="widget.Action.Read" widgetRefId="niSpeedMax">	 
					<Method name="GetValue"/>
				</ReadTarget>
			</Operand>
			 <EventHandler condition="ManualSpeed&lt;ManualSpeedMax"> <!-- Speed < Speed max --> 
				<Action>
					<Target xsi:type="widget.Action" widgetRefId="niSpeed">
						<Method name="SetValue" value="=ManualSpeed+1" />
					</Target>
				</Action>
			</EventHandler> 
		</EventBinding>
		
		<!-- Decrease Speed -->
		<EventBinding id="DecreaseSpeed">
			<Source xsi:type="widget.Event" widgetRefId="pbSpeedDown" event="Click" />
			<Operand name="ManualSpeed" datatype="ANY_REAL">
				<ReadTarget xsi:type="widget.Action.Read" widgetRefId="niSpeed">	 
					<Method name="GetValue"/>
				</ReadTarget>
			</Operand>
			<Operand name="ManualSpeedMin" datatype="ANY_REAL">
				<ReadTarget xsi:type="widget.Action.Read" widgetRefId="niSpeedMin">	 
					<Method name="GetValue"/>
				</ReadTarget>
			</Operand>
			<EventHandler condition="ManualSpeed&gt;ManualSpeedMin"> <!-- Speed > Speed min --> 
				<Action>
					<Target xsi:type="widget.Action" widgetRefId="niSpeed">
						<Method name="SetValue" value="=ManualSpeed-1" />
					</Target>
				</Action>
			</EventHandler> 
		</EventBinding>

So thanks again for the very fast reply!

3 Likes