Calling a cicode function from a page event doesn't work at times

Further to an earlier post about passing a cicode global variable argument into a function that is called by a super genie graphic window, I have got all the code working properly thanks to the wonderful help from this community!

It seems now the problem I have is that the function is not always called when the supergenie window is called. I have created a variable on the supergenie window that tells me if the code has been executed and in some cases it has not.

The variable that is set true by the code, so I then created a 'while do' loop to try and execute the code continuously until the variable is set true.

I think the problem is that for some reason the page event doesn't always run when the page (supergenie) is called and leaves check variable false, indicating the code has not been executed.

I have read all the help documentation and believe everything is correct. The documentation notes that there can be issues when using the 'on page entry' event so I have used 'on page shown event'. I note that the 'while page shown' event does not at work at all and not sure why this is.

Any help appreciated

Regards

Daryl

Parents
  • Two possible causes I can think of right now:
    1. If no user is logged in when opening the page, the tag cannot be written to (standard security feature).
    2. The statements take too long (blocking) and the event is aborted while not finished. To overcome this you can put the statements in a cicode function and then call that function from the event using TaskNew().

Reply
  • Two possible causes I can think of right now:
    1. If no user is logged in when opening the page, the tag cannot be written to (standard security feature).
    2. The statements take too long (blocking) and the event is aborted while not finished. To overcome this you can put the statements in a cicode function and then call that function from the event using TaskNew().

Children
  • In addition to moving the code to a function called by TaskNew, you could:

    1. Add the command: ErrSet(1) to the beginning of the function. That keeps citect from terminating the task if one of the commands causes a fatal error. 

    2. Add a TraceMsg() call to the beginning and end of the function. For example: 

    Tracemsg("TrendFn started");

    ...

    TraceMsg("TrendFn finished");

    That way you know for sure if the function gets called and finishes successfully. You could also check the return value from each BlockedTrnSetPen call or step into them in the debugger to make sure they are successful. 

    You could also consider using the Process Analyst trend viewer instead of the legacy trend viewer.

    With the legacy viewer, TrnSetPen will fail until the trend object initializes, which depends on the speed of the trend server and whether it is on the local machine. 

    Process analyst uses a different function to set pens and shouldn't have that problem. 

  • Thanks again for your help

    I have successfully added the trace messages as suggested.

    I have used the debugger to step through the code on the SCADA servers and looks to be working perfectly.

    The problem is only on the workstations which to not have studio installed, hence no access to debugger where the problem is occurring.

    The TraceMsg help says Displays a message in the Kernel and Debugger debug windows. Do you know which kernel window ?

    kindest regards

    Daryl

  • Hi Patrick, for No.1 when user is logged out, can this be allowed to run cicode when a user is logged out? I need a heartbeat to PLC running always to let the PLC know the client is online.

  • Running cicode will work when no user is logged in, but writing tags will not.

    To overcome this, there are a few options. I will list them in order of security (least secure at bottom):

    1. Create a mechanism on a server component (report server for example) that will check for online clients and set variables accordingly. This is the most secure, but also the most difficult solution.

    2. Create a dummy Role and User with no privileges and areas. On every Client, create a startup cicode script that will log in this user by default. Also make sure you create an alternative logout function as well that logs in this dummy user instead of logging out. This will allow clients to write to tags while "logged out".

    3. From the client call a function on a server component using RPC (ServerRPC / MsgRPC). The server function will write to the variable. For this you have to set "Allow RPC" to TRUE in configuration of the server component. Also, you have to create and use the dummy user and role descibed in option 2, and set "Allow RPC" to TRUE for this dummy Role as well.

  • When you say 'know the client is online', what do you mean? Do you have multiple PlantSCADA clients and the PLC needs to keep track of each one of them?

    Or, do you just have one Plant SCADA PC that is both a server and client? If that's the case, then as long as you are running in Multi-Process mode (selected in the Setup Wizard), you can just define an event that toggles your heartbeat bit. Then run the Setup Wizard and enable that event to run on the I/O Server process. The server processes by default have full privileges, even if no user is logged in to the client process.

    This screenshot is from the Power edition of Plant SCADA, but it's the same thing. Also, I like to name the event according to the PC or process where it should be run. You can have multiple events with the same name (it's really like a group name). It makes it a lot easier in the future when someone is running the wizard and may not be familiar with the events and what should run where.