The GseosBlocks allows easy access to the GSEOS block definitions. One way of accessing blocks from a script is to import the __main__ module. However, this will pull in all names from the __main__ module if imported with from __main__ import * and we recommend against this technique. The other option would be to prefix every block with __main__ or to specifically import the blocks needed in your script like from __main__ import TLM, which is the technique we favor. An alternative to using the block definitions is to use the GseosBlocks module which makes the blocks available via the Blocks dictionary.
It provides two containers that allow access to blocks:
Blocks: This dictionary is keyed by block name and contains objects of type TBDMBlock.
BlocksByHandle: A list that is keyed by block handle. The values contained are objects of type TBDMBlock. See below for a description of these objects.
TBDMBlock
Every block you define in your block definition files is instantiated as a TBDMBlock object and when you access a block it will be through the TBDMBlock class. You should never instantiate any objects of this class yourself. All block items can be accessed like regular attributes. Keep in mind that when writing data to a block item it will be be published until you invoke the SendBlock() function on the block. The blocks define the following attributes you might access:
strName: The name of the block.
Items: A list with all the scalar items names of this block
bEnableSelect:This attribute controls if the block is displayed in the block and item select dialog boxes. This lets you simplify the user interface for complex configurations (i.e. multipe instruments defining all their blocks). By default EnableSelect is True, if you set it to False the block will be taken of the select list. However, the block is still accessible from Python and is otherwise not changed at all.
The following sample removes all blocks with block names starting with 'XRS_' from the select block and select item dialog:
#
# Remove all blocks starting with 'XRS_'
#
import GseosBlocks
for strBlockName in GseosBlocks.Blocks.keys():
if strBlockName[:4] == 'XRS_':
GseosBlocks.Blocks[strBlockName].bEnableSelect = False
Multi-threading and GSEOS block access
Blocks are shared resources in GSEOS. If you plan on using multiple threads of execution and to write to blocks and to send blocks from these threads you have to deal with thread synchronization.
GSEOS Sequencers use threading, so if you generate blocks from your sequencer you have to deal with thread issues.
If you write to a block from multiple threads you can use Python's lock mechanism to ensure your writes are consistent. However, if the same block is generated from the main thread without honoring this lock there will still be contention.
The solution is to use the TThreadSafeBlock class. You would create a new instance of this class for each thread and each block you want to modify in that thread.
The following example illustrates this:
#
# Get thread safe block access from multiple threads.
#
import time
import thread
import GseosBlocks
oThread1TLM = GseosBlocks.TThreadSafeBlock(TLM)
oThread2TLM = GseosBlocks.TThreadSafeBlock(TLM)
def f(oBlock, wValue):
while 1:
for i in range(len(oBlock.Data)):
oBlock.Data[i] = wValue
oBlock.SendBlock()
time.sleep(0.1)
thread.start_new(f, (oThread1TLM, 55))
thread.start_new(f, (oThread2TLM, 77))
To create a new TThreadSafeBlock object you pass the block object you want to create thread safe access to into the constructor. In the above case this is the TLM block. You have to create a TThreadSafeBlock object for each thread you create and each block you want to generate in that thread. You can access the oThread1TLM and oThread2TLM blocks just like regular block objects. That is you can write items, read items, and send off the block once you are done with it.
There is no locking necessary when using TThreadSafeBlocks and all access to the underlying block is properly synchronized.
As opposed to a regular block object you can not install Decoders or Monitors on a TThreadSafeBlock, please use the regular block to handle decoders and monitors.