We are using Codesys for heavy industrial machinery.
One thing our technicians have to do is to manually operate the system. For that, we have a Webvisu running on a panel pc, with several Tap buttons. They hold the button to operate an hydraulic piston for example.
In my tests I noticed that if, for some reason, the connection is lost while a button is pressed, it will stay pressed. This is very dangerous and can end up in heavy damage.
I'm looking for a way to avoid that. Tried to look at visustructclientdata. But it takes too much time for the client to disconnect. I tried to change the timeout on visustructclientdata, without any success...
Any ideas how to avoid disaster?
With visustructclientdata.GlobalData.LastUsage you can detect, if the webvisu connection is active:
//RemotePanel letzter Zugriff ermitteln
IF pClientDataRemotePanel<>0 THEN
tofRemotePanelUsage(IN:= xRemotePanelUsage, PT:=T#300MS);
heaviest thing is, to get the correct visustructclientdata of the webvisu by iterating all active clients.
this is also very interesting for me.
In another topic I published my code to iterate all the clients...I tried to evaluate when a client disconnects...but it was to slow.
But may with "LastUsage" it will work...:-)
It is in German but you can Download there an example.
I want to do this for a WebVisu Client...
Can you give me an example how to do? I can't find "LastUsage" :-)
LastUsage exists, but is not shown after typing "." (autofill)
I think because you only can get it by a pointer to the visuVisuStructClientData.
Set a breakpoint in your while of the iteration an if a visuclient is active have a look at the pclient variable: in my case now I have only the visu of the programming system active:
found it... but how to use it? If you want to have the data you have to use it in the Method "HandleClient" of FB "VisuClientIteration"
I can't find a solution to use this data...Do you know a solution?
i added the following lines to the while loop of the iteration, like you posted above:
IF pClientData^.GlobalData.ClientType=Visu_Clienttype.WebVisualization THEN
and out of the while this code:
tofRemotePanelUsage(IN:= xRemotePanelUsage, PT:=T#300MS);
That's my solution, I don't know how to do it with the methods.
Ok, now I know what you mean :-)
This will work for WebVisualization in general... When you have two active Visus and one is no longer active.... I think I need an Array to detect each Visu
for security i check the ip adress of the webvisu clients and only the known client is allowed to start special action and if this one get's lost, the process is stopped!
Hi dkugler, how did you manage to only allow certain IP addresses to start an action amongst other IP addresses?
OK. I Managed to use this code and it partly works. but I still have a problem:
Assuming operators devices loses the browser focus for some reason, the button stays pressed!
this is very dangerous. previous solution still recognize the client, but button will not stop the tap...
I set the variable of the button to false if Visu is not longer working.
But for that I need an Array if more Clients are active because with the code of dkugler you have allways active Visu if more clients are active.
I'm still testing this function... here my code till now. (Trigger if one client will become active or will lose connection)
Hope this will help you
This is inside of the while loop:
IF pClient^.GlobalData.ClientType=VU.Visu_Clienttype.WebVisualization THEN
Outside of while loop:
IF NOT TOF_Timeout.Q THEN
xVisuNotActive:=TRUE; //Diese Variable muss mit Steigender Flanke ausgewertet werden
IF TON_Reset.Q THEN
//Check if one Visu is no longer active
IF xCheckSameAgain THEN
IF (timLastWebVisuUsage[iSaveClientIdOfStopVisu] > timLastWebVisuUsage_old[iSaveClientIdOfStopVisu]) THEN
IF NOT xCheckSameAgain THEN
FOR i:=-1 TO 100 BY 1 DO
IF NOT (timLastWebVisuUsage[i]=T#0S) THEN
xWebVisuInUsage:=(timLastWebVisuUsage[i] > timLastWebVisuUsage_old[i]);
IF (timLastWebVisuUsage[i] <= timLastWebVisuUsage_old[i]) THEN
Just some uninformed two cents.
Why not hardwire this this functionality to a physical button instead..
Because I want to use a Button on my touch-Panel :-) => Sometimes not possible to Wire a Hardwire-Button
i use this solution only for not safety relevant functions! generally the hardwired estop is necessary! In my case the only client which is allowed to start/stop is a web panel from Berghof Automation with known ip. The browser app is the only active application and focus is fixed there, so i never had the problems like you. Only thing was, if network connection got lost. For checking and synchronising several modes, user login etc, i use a array of struct for each client and manage there the actual states. How to get the ip adress i found in the webvisu client example in the store. Search for a helper method/function. At thursday i will be back in the company. Then i'm able to take a code snipplet of that. I'll do a check, what happens if the button is pressed, connection get lost and comes up again. Because we use hybrid cabels with power and ethernet, the panel reboots. to test what happens if only ethernet get disconnected is a good question!
Yes thats true.. for safety functions you need a hardwired estop! In my case not necessary :-)
Because of IP-Adress...
Here I also postet a Project to download, where you can use the IP-Adress...try this.
Just because you can, doesn't mean that you should.
What damage (human, environment, product/machine) is to be expected when the button in question is NOT available while the button was pressed?
Thanks for the reply @dkugler, my problem is also relevant to @Iota application.
Our remote panels are for display purposes only, so how do I disable inputs from these WebVisu instances?
Sorry, I meant @Chris.O, my appologies
Just one Idea:
e.g. create an array xSwitchOn:ARRAY[-1..uiMaxNumbClients] of BOOL;
and with your Button switch "xSwitchOn[CurrentClientID]" to TRUE
Inside your programm you can Iterate over all Clients and see ClientID as well as the IP-Adress.
Make a For-loop (or inside the Iteration) and check if the "xSwitchOn" is TRUE and if IP-Adress is the same then your enabled one. Then set your "generalxSwitch" to TRUE... else set switch back to FALSE.
Just an Idea
@Chris.O: Alright that would work, but would be very tedious to set up for a large program. Also, it might be tricky to handle for Numpad inputs and such??
Is there a global variable available that disables all inputs coming from a specific IP address? This would be the ultimate solution.
I don't think so... but may be you can activate user management. You also can logout via IEC-Code.
So for Input in general you need then a User with password. If IP-Adress is "disabled" then log out this user automatically...
may be in that way...
That may be the way to go.
Could I limit the number of user logins to 1 at a time? Meaning, if I have one WebVisu instance open and am logged in as User1, then another person logs into a second instance of Webvisu as User2, User1 automatically gets logged out?
You can activate "CurrentVisu variables" inside the Viz-Manager (see Attached file)
Inside the Online-Help is written:
"The application recognizes and uses the global variable VisuElems.CurrentVisu of type STRING. It contains the name of the active visualization at application runtime.
In the application code, the variable can be read in order to retain the name of the active visualization. The variable can be written to for calling a switch of visualizations. The switch is done at the same time on all display devices.
Example: A TargetVisu display variant and several WebVisu display variants are active. When the CurrentVisu variable is written to, all display variants switch to this visualization.
Requirement: The application includes a visualization that calls other visualizations.
Assignment of variable: VisuElems.CurrentVisu := strVisuName;
Assignment of visualization name: VisuElems.CurrentVisu := 'visu1';"
May you can use this? I don't know how it works with different users.. I think ther is no influence on the users...
But I think you can do your wish on your own... you can also get the current logged in User for the different Clients with the Client iteration.
Then you can say if user is logged in twice, log out the old one...But I think it's a little bit of code :-)
Yes I am already using the CurrentVisu variable in my program, but it has no reference to the login. Basically all Webvisu and TargetVisu instances show the same visu at all times. If one visu changes, they all change.
I am looking for a way to limit the inputs to only one single visu instance, wether it would be a TargetVisu or a WebVisu.
I am thinking that I need to find a way to limit the number of simultaneous logins to 1 at a time. This would allow me to restrict input to one single screen and would be the easiest to implement.
Do you know of a variable that keeps track of user logins? For example, if user1 and user2 are logged in, then loginCount = 2...
Log in to post a comment.