We are currently using the same dataProvider array for multiple dropdown boxes on our MappView application to dynamically set inputs for a vision system on our machine.
Our current issue with this is that we are unable to filter out the array indexes that we have already assigned for a specific vision input and thus we can select the same input channel for multiple vision functions, such as camera ready and camera data valid.
I know on VC4 we were able to use the OptionDatapoint function on the dropdown list box to assign a value of 2 for the array indexes that were already assigned, thus hiding them so they could not be assigned for another channel.
Is there a solution that is similar to this OptionDatapoint in MappView? If not, is there a recommended way of filtering this dataProvider?
Any help in this matter would be greatly appreciated.
One way to do this would be to build the dataprovider string on the PLC code and then bind it via OPC UA. Not the easiest or cleanest way to do this but should get the job done.
In latest mapp View versions, you have mapp Script available.
This way you could use a generic data provider, which you modify in some scripts to your current situation.
This can easily be done by listening on change events (OPC-UA, …) and triggering some functions. As you have the full functionality of JavaScript is should be much easier to adjust the data provider within the scripts - compared to PLC program.
Just to give you an idea:
This sample creates a dynamic data provider. The basis of the data provider is read from a OPC-UA variable - of course you could store it also in a local variable, etc.
Based on a “MaschineConfiguration” the data provider is modified (elements removed). Finally the new data provider is assigned to the widgets.
The second function adds a “valueChanged” listener to the “MachineConfiguration”, so that the data provider is adjusted, if the config changes.
async function updateDropDownList(config =-1) {
const listElements = [];
let result = await opcua("::Program:ListBoxContent").getValue();
let machineConfiguraiton = config;
if (machineConfiguraiton === -1) {
machineConfiguraiton = await opcua("::Program:MachineConfiguration").getValue();
}
for (let i = 0; i < result.length; i++) {
if ((machineConfiguraiton === 0) && (i > 1)) {
continue;
}
listElements.push({
value: `${i}`, text: `${result[i]} - ${i}`
});
}
widgets.DropDownBox1.setDataProvider(listElements);
}
opcua('::Program:MachineConfiguration').valueChanged(function (e) {
updateDropDownList(e.detail.newValue);
});
(I agree - a little more work compared to the VC4 approach … but also much more flexibility and possibilities!)
Thank you for providing a comprehensive solution. As of right now, we have not applied this to our system, but we may look to implement this in the future.