SFC Steps in IEC 61131-3 Programming - iec61131-3

So I have a problem where in my SFC it jumps to an inital step but the commands written in the step would not register.
At the end of the SFC a step inputs 5 into A_Status(INT).
The very next transition checks if the value of A_Status is 5.
No problems so far, but after the transition when it jumps to the start of the SFC,
where the first step is supposed to input 0 into A_Status, A_Status stays at 5.
The cycle time of my program is 100ms. I have tried slowing the cycle but it didn't work.
What seems to be the problem here? Maybe the same variable used in such a sequence just doesn't work?
Reply would be greatly appreciated.

You don't mention if you write the values during Entry/Exit or in the SFC step actions. But beware, that on some occasions code from a previous step can be executed later than code in the new step.
Here is a link that explains the call order and why sometimes parts of the code is executed twice:
https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_plc_intro/45035999420423563.html
I've had succes with adding the following code in all the actions to prevent this from happening.
IF STEP_NAME.x THEN // Only execute this while the step is active.
// Insert code here.
END_IF

Related

Pause then resuming simulation in Anylogic

I would like to give the user a button that allows them to skip ahead 1 hour in the simulation and then continue running the model if play is clicked. The code below allows the user to skip ahead an hour, however they are unable to resume the simulation when play is clicked.
double nextHour = time() + 60;
pauseSimulation();
getEngine().runFast(nextHour); //Runs the model to the next hour when button is clicked
Any help much appreciated.
Try adding runSimulation() after the last line. But probably, that does not work. In that case:
Create a dynamic event (not the normal event) with the line runSimulation() in its action code.
In the button code, before the runFast... line, write create_MyDynamicEvent(1, HOUR). This will trigger the even 1 hour later and unpause the model.
AnyLogic Support suggested the following solution, which I have used:
Unfortunately, Ben's suggestion didn't didn't work; it seems to cause an issue when pauseSimulation() is used.

Talend ETL - running child job in tLoop

I am trying to run a child job in tLoop. The child job connects to salesforce and downloads "Account" object to local SQL Server table. There are problems with connection to Salesforce, it takes few attempts to connect. Hence, I put the connection stuff in child job and now trying to call the child job in a loop. Below is the image of my parent job.
As you can see in image the tRunJob_1 has error because of Salesforce connection problem in child job. This is correct behaviour.
The setRetryConnect that is connected to OnComponentError has this code: context.retryConnect = true;
The setRetryConnect that is connected to OnComponentOk has this code: context.retryConnect = false;
So, I am tripping this context variable depending on whether child job succeeds or fails.
My tLoop looks as below:
I want the tLoop to run as many times till the condition remains true. That is till the time it continues to error out. However, it just iterates once and then stops. Could anyone please let me know what correction need to be done here to make the tLoop work?
I couldn't re-pro your issue with SalesForce but by looking at your job what I feel is that when you say - "it just iterates once and then stops" is the expected behavior.
As per your job flow after the tRunJob you are using OnComponentOk/OnComponentError trigger which would process and stop the job run as it would have completed the job execution. What it would have ideal was to keep everything in a subjob post tLoop so that it will iterate till the condition is met.
Sample job for explanation -
Here used tSetGlobalVar to define a global variable (in place of your context variable). Then use the globalMap variable as ((Boolean)globalMap.get("tLoop")) in your "Condition" for the tLoop.
And then finally run some code in the tJava component that does something and conditionally sets the global variable to false to mark the ending of loop.
tRunJob provides an Return Code ((Integer)globalMap.get("tRunJob_1_CHILD_RETURN_CODE"))
If you're running your child Job a number of times and want your Job to exit with non-Zero if one of these iterations fails, then after each iteration, you should test this return code and store it in your own globalMap Object if it is non-zero
int returnCode = ((Integer)globalMap.get("tRunJob_1_CHILD_RETURN_CODE"));
if (returnCode > 0) {
globalMap.put("tLoop", false);
}
else {
System.out.println(returnCode);
};
Found the answer myself, posting it here so that it may help others. It appears like OnComponentError breaks the tLoop. Disabled the OnComponentError flow and un-checked the 'Die on Child Error' checkbox in tRunJob.
The tLoop remains as it is. No changes here.
The retryConnect will use the below code. It uses CHILD_RETURN_CODE to check whether the child job threw error. In case of success, its value is 0. I am tripping the variable when the child job succeeds, so the loop will stop. As you can see, the tLoop shows 2 iterations, it is working as expected now. Thanks.

How to call the controller task on each 1 min interval

I have created task on controller and there is loop which is loading for 100 times.
Now I want to load it for 25 times and pause that loop for 1 min and after that it will execute next 25 items same for next 25.
I have checked it with sleep but its not working.
Can you please advise me if is there any way on plugin event or any other method.
Thanks
This is actually unrelated to Joomla! Since you're creating a long running process you need to start it with something else than a browser. A CRON job is a good idea here if you want to execute this operation multiple times. Otherwise it can run via command line. Make sure the max_execution time setting of PHP does not cause any trouble.
If you still need this within Joomla please have a look at the CLI documentation.
https://docs.joomla.org/How_to_create_a_stand-alone_application_using_the_Joomla!_Platform

Confusion regarding usage of event.triggered

I'm trying out some code that is supposed to block until moving to a new simulation time step (similar to waiting for sys.tick_start in e).
I tried writing a function that does this:
task wait_triggered();
event e;
`uvm_info("DBG", "Waiting trig", UVM_NONE)
-> e;
$display("e.triggered = ", e.triggered);
wait (!e.triggered);
`uvm_info("DBG", "Wait trig done", UVM_NONE)
endtask
The idea behind it is that I trigger some event, meaning that its triggered field is going to be 1 when control reaches the line with wait(!e.triggered). This line should unblock in the next time slot, when triggered is going to be cleared.
To test this out I added some other thread that consumes simulation time:
fork
wait_triggered();
begin
`uvm_info("DBG", "Doing stuff", UVM_NONE)
#1;
`uvm_info("DBG", "Did stuff", UVM_NONE)
end
join
#1;
$finish(1);
I see the messages Doing stuff and Did stuff, but Wait trig done never comes. The simulation also stops before reaching the finish(1). One simulator told me that this is because no further events have been scheduled.
All simulators exhibit the same behavior, so there must be something I'm missing. Could anyone explain what's going on?
The problem is with wait (!e.triggered); when e.triggered is changing from 1 to zero. It has to change in a region where nothing can be scheduled, so whether it changes at the end of the current time slot, or the beginning of the next time slot is unobservable. So the wait will hang waiting for the end of the current time slot, which never comes.
I think the closest thing to what you are looking for is #1step. This blocks for the smallest simulation precision time step. But I've got to believe there is a better way to code what you want without having to know if time is advancing.

Calling a method from ABL code not working

When I create a new quote from Epicor I would like to add an item from the parts form automatically.
I am trying to do this using the following ABL code which runs when 'GetNewQuoteHed' is called:
run Update.
run GetNewQuoteDtl.
run ChangePartNumMaster("Rod Tube").
ttQuoteDtl.OrderQty = 5.
run Update.
I am getting the error:
Index -1 is either negative or above rows count.
This error occurs for each line in my ABL code.
What am I doing wrong?
That's not the proper format for a 4GL error message (nor is it at all familiar) so I'd say it is an Epicor application message. Epicor support is probably your best bet. However... Just guessing but it sounds like you might need to somehow initialize the thing that you're updating.
Agree with #Tom, but i would also say try and isolate the error and see where the error is raised as soon as you find the point the error is actually raised it is normally much easier to figure out exactly what is going wrong and how to solve it.
Working between a 0 based and a 1 based system there can be issues with the 1st or last entry depending on which way you moving. As the index for 0 based systems starts at 0 and ends at n-1 where 1 based systems start at 1 and end at n.