Keyboard Shortcuts
Likes
Search
LogixNG - Sanity check and guidance
Hi folks,
?
First of all, just to say that I am finding LogixNG pretty amazing. A bit of a learning curve but, so far, it has handled everything that I have dreamed up without the need to start writing Jython code.? I do just want to share what I have been doing to make sure that I am on the right track. I also have one specific question.......
?
I have a LogixNG which is set to run at startup:
?
?
It has several Conditional NGs within it:
?
?
I can see that they run sequentially - is my assumption that each one will finish before the next one starts correct??
?
I think I can see that when one of the NGs talks to MERG CBUS, it does so asynchronously. In other words, the execution of the NGs carries on whilst CBUS "catches up".? For example in the Sensors Conditional NG.....
?
?
....somewhere in the background A1 causes a whole load of status requests to be sent to CBUS.? I have tried to make the NG hang around for a bit with the operation at A2. I am not sure whether that is supposed to work as I am expecting? Assuming it does, then am I right that the Sensors Conditional NG will tell some other part of JMRI to send all of the status requests and will then wait ten seconds before the next Conditional NG (Points) runs?? If not, then a pointer would be appreciated as to if/how I can "slow down" progression through the Conditional NGs.
?
Better still, and I suspect the answer is "no", is there any way in a Conditional NG to say something like "wait until there are no more messages [from JMRI] being sent to CBUS"?? That would be a lot neater than using an arbitrary time delay.
?
Thanks for reading, and any advice would be very welcome.
?
Cheers,? Nick
?
?
?
|
¿ªÔÆÌåÓýHi Nick, Nice to hear that you appreciate LogixNG! It might be possible to add support for checking if the send queue is empty. I have asked on the JMRI developers list about it. > I can see that they run sequentially - is my assumption that
each one will finish before the next one starts correct? Assuming that the ConditionalNGs are running on the same thread, which is the default, only one ConditionalNG can run at a time. So they have to wait for each other. I don't recommend that you have the ConditionalNG running but
stopped waiting for something to happen. Instead, I recommend that
the "Execute A after 10 seconds" has a child action that sets an
internal sensor and that the ConditionalNGs that should wait
checks if that sensor is active before doing their stuff. Daniel
On 2025-04-21 10:57, nicklocke via
groups.io wrote:
|
Thanks Daniel.
?
Much appreciated that you took the trouble/time to ask on the JMRI developers list.? I can see that Bob has replied, but it looks like I don't have access to answer there. Bob makes a good point about responses not necessarily being received, although the send queue becomes empty. In my specific use case, that is fine though. All I am trying to prevent is more and more messages being added by the NGs, making the send queue longer and longer- the responses coming back later "asynchronously" is fine.?I do agree with Bob's point about possible user confusion though.
?
Thanks for confirming that the single threading is going to work how I expected.
?
I think I might be missing something with your recommendation though. All I am trying to do with the "Execute A after 10 seconds" is make sure that there is time to breathe before the next ConditionalNG kicks into life. I agree that if they were running "all over the place" then it would make sense to use an internal sensor. But here, I am running the ConditionalNGs once when JMRI starts and never again. So, unless I am missing something (which is very likely), I can't see any functional difference between:
?
Maybe though, good practice says I should use the internal flag approach, just in case the ConditionalNGs are not always only run at startup in the future.
?
Thanks, Nick. |
¿ªÔÆÌåÓýNick, The problem with your solution is that the action "Execute A after 10 seconds" does not stop the ConditionalNG. The ConditionalNG continues to run and stops as soon as all the actions are completed. And then the rest of the ConditionalNGs run. The "Return" action is executed after 10 seconds, but at that time the other ConditionalNGs have already been run. I could add a new LogixNG action "Wait" that would stop the ConditionalNG from running for some time, but it would be bad programming practice to use it. And there is a huge risk that non experienced users would use it in a bad way. LogixNG is intended to be used also by users which are not experienced developers but want to do some programming. The solution I gave you with the internal sensor will keep the other ConditonalNGs from doing their stuff before they are supposed to do so. Daniel On 2025-04-21 16:59, nicklocke via
groups.io wrote:
|
Hi Daniel,
?
I think I understand now. In my mind, I was over-simplifying the "single thread" idea.? So was thinking that the "Execute A after......" would block the thread for ten seconds, then execute the "return" and only then would the next ConditionalNG get access to the thread and be able to run. I think your "only one ConditionalNG can run at a time. So they have to wait for each other" threw me a little bit.
?
Internal Sensors coming right up!
?
I agree that implementing "wait" would be wrong!
?
Please may I also ask the best way to introduce a variable into the "Execute A after....."?? I have another ConditionalNG, again running only at startup. It requests that various Turnouts move to their startup positions and, obviously I don't want all the servos to move at once, so have used "Execute A after...." to set a turnout, then wait, then set another turnout and so on. Empirical evidence suggests that is working fine!?
?
?
I hope that is a legitimate use of "Execute A after...."!
?
But I would like to avoid repeatedly hardcoding "1" in each of the many places where I am waiting. I tried adding a Memory Variable......
?
?
.....with the intention of then having something like:
?
But, there doesn't seem to be an obvious way.? Trying "reference", unsurprisingly won't save. Trying LocalVariable or Formula save, but then fall over at run-time, again unsurprisingly as I have a Memory Variable not a Local Variable or a Formula . If you have time, it would be great to have a view on how best to introduce a variable (which ideally needs to be visible across multiple ConditionalNGs).
?
Thanks, Nick
? |
Nick, For your turnouts, you might look at using a Route instead of LogixNG. ?It is designed to set a group of turnouts with a delay between each one. You can use LogixNG to trigger the route. Dave Sand ----- Original message ----- From: "nicklocke via groups.io" <nick.locke=[email protected]> Subject: Re: [jmriusers] LogixNG - Sanity check and guidance Date: Monday, April 21, 2025 3:01 PM Hi Daniel, ? I think I understand now. In my mind, I was over-simplifying the "single thread" idea.? So was thinking that the "Execute A after......" would block the thread for ten seconds, then execute the "return" and only then would the next ConditionalNG get access to the thread and be able to run. I think your "only one ConditionalNG can run at a time. So they have to wait for each other" threw me a little bit. ? Internal Sensors coming right up! ? I agree that implementing "wait" would be wrong! ? Please may I also ask the best way to introduce a variable into the "Execute A after....."?? I have another ConditionalNG, again running only at startup. It requests that various Turnouts move to their startup positions and, obviously I don't want all the servos to move at once, so have used "Execute A after...." to set a turnout, then wait, then set another turnout and so on. Empirical evidence suggests that is working fine!? ? ? I hope that is a legitimate use of "Execute A after...."! ? But I would like to avoid repeatedly hardcoding "1" in each of the many places where I am waiting. I tried adding a Memory Variable...... ? ? .....with the intention of then having something like: ? But, there doesn't seem to be an obvious way.? Trying "reference", unsurprisingly won't save. Trying LocalVariable or Formula save, but then fall over at run-time, again unsurprisingly as I have a Memory Variable not a Local Variable or a Formula . If you have time, it would be great to have a view on how best to introduce a variable (which ideally needs to be visible across multiple ConditionalNGs). ? Thanks, Nick ? |
Thanks Dave and Daniel,
?
I am now using routes (triggered by LogixNG) which makes the actual setting of the turnouts at startup a lot easier. I am using the feature which sets a sensor when all of the turnouts have been told to move to trigger the next ConditionalNG.? So that combines both your recommendations. Everything seems to be working as expected now.
?
Thanks again for the support and guidance.
?
Nick |