Overivew

 

The Sammi 7 provides the support for scripting using the python scripting language. Python is a popular and versatile scripting language that has active development and community support. More information regarding python can be obtained from its official website www.python.org.

 

By embedding the powerful python script interpreter with Sammi and exposing various Sammi functionalities using python interfaces, Sammi 7 provides a set of features to improve different phases of Sammi application development process such as designing and creating formats, automating format testing, verifying created formats, monitoring and debugging format data updates at runtime etc. The sections Applications of Scripting and Roadmap provide some glimpse of what type functionalities can be achieved by leveraging scripting capabilities in Sammi.

 

Sammi Python Interfaces

 

The interfaces described below are used to get access to Sammi functionalities at runtime and design time.

 

  • Sammi Object Model (som)The som module is a critical component for exposing Sammi’s object model to the python scripts. The module can be used with Sammi runtime, design time and even with stand alone python scripts. The primary purpose of the module is to provide access to attributes associated with Sammi objects such as: format, layer, shape, ddo, composite etc.
  • Runtime Environment (rte)The rte module can be used at runtime (with s2_event process) or at design time (with s2_fred process). The module provides a method to process Sammi commands in Sammi. It also provides a way to get a list of currently active formats in Sammi.
  • Format Editor (fe)The fe module can only be used at design time (with s2_fred process). The methods exposed via this interface are primarily for interaction with design time functionalities.

 

execute-script command

 

  • Usage: execute-script file_name  (i.e. execute-script example1)The execute-script was added for executing python scripts in Sammi. Just as the add-window command searches the folders specified in the SAM2_DATAFILE environment variable for adding the format, the execute-script command will also use the SAM2_DATAFILE to search for the python script to execute.

 

Applications of Scripting

 

  • Sammi Studio

    The Sammi studio is a good example of how scripting capabilities in Sammi is utilized to provide an improved integrated development environment (IDE) for designing and creating formats in Sammi. The Sammi studio uses the combination of python scripting language, Sammi python interfaces and PySide library (the python binding for the popular Qt framework) to create MDI interface. By using the Sammi python interface, the studio application is able to query the existing format that is being edited and make the attributes of the format available for better visualization and manipulation. The major features of the Studio and the role that scripting plays in achieving these features are briefly described below:

    • The MDI

      Key Features: The MDI interface in studio provides a container environment for the IDE. It is responsible for managing menu, toolbars, panels, dialogs, and mdi subwindow. It also acts as a controller for delegating specific responsibility/events from the format designer to the appropriate widget/panel.

      The Role of Scripting: The script file $SAMMI/data_fe/mdi.py file is responsible for implementing these MDI responsibilities.

    • Menubar and Toolbar

      Key Features: The menu and toolbars in studio allows user to manage format designer surface. The various icons for the menubar and toolbars are located in the $SAMMI/bin/mdi_imgs/toolbars folder.

      The Role of Scripting: The interaction between the format designer surface and menu/toolbar primarily happen using Sammi commands. The send_command method from the rte module is used to execute format editor specific commands. The code for menubar and toolbar is implemented in $SAMMI/data_fe/mdi.py file.

    • Tool Box and Shape Panel

      Key Features: The toolbox and shape panel in Studio allows user to create ddo and shape object on the format designer surface. The interaction between format designer surface and menu/toolbar also primarily happen using Sammi commands. The $SAMMI/data_fe/toolbox.xml file is used to load the settings for the tool box panel. The $SAMMI/data_fe/toolpanel.xml file is used to load the settings for the shape panel. The images for these panels are loaded from $SAMMI/bin/mdi_imgs/toolbox and $SAMMI/bin/mdi_imgs/shapepanel folders.

      The Role of Scripting: The interaction between format designer surface and menu/toolbar also primarily happen using Sammi commands. The functionalities are implemented in $SAMMI/data_fe/ddo_toolbox.py and $SAMMI/data_fe/shape_panel.py files.

    • Project Explorer

      Key Features: The project explorer panel allows easy access to Sammi project related files. The panel loads the content based on the SAM2_DATAFILE environment variable. The project explorer panel presents a logical group of the Sammi project based on its file type.  The search box in the panel allows easy search for a particular file by name. The file is opened by  double-clicking on the file. In addition to this, the files under the Components folder can be drag and dropped to the format designer surface. The project explorer also provides a UI to load and unload formats/composites/vector symbols/ddo libraries.

      The Role of Scripting: These functionalities are implemented in $SAMMI/data_fe/proj_explorer.py file. The primary interaction of project explorer with Sammi happens via Sammi commands.

    • Data Configuration Panel

      Key Features: The data configuration panel allows easy access to configure data access properties for the selected ddo. As a ddo is selected on the format designer, the configuration panel loads the ddo’s data access properties into the panel. In addition to this, the panel also allows quick modification of a ddo name. The view tags option allows data access information to be loaded from pre-defined $SAMMI/data_fe/sammitags.config file.

      The Role of Scripting: The data configuration panel uses the som module to modify the ddo data access properties. The $SAMMI/data_fe/data_config_panel.py file is responsible for implementing these functionalities.

    • Layers Dialog

      Key Features: The layer dialog is responsible for providing a way to manipulate layer properties.

      The Role of Scripting: The dialog uses Sammi commands and interfaces from the fe and som modules to access and manipulate layer properties for the format being edited. The $SAMMI/data_fe/layers_dialog.py file is responsible for implementing these functionalities.

    • Command Window

      Key Features: The command window allows Sammi commands to be executed. It also maintains the command history of successful commands that were entered.

      The Role of Scripting: The $SAMMI/data_fe/cmnd_win.py file is responsible for implementing these functionalities.

    • Object Explorer Panel

      Key Features: The object explorer panel in Sammi studio provides multiple functionalities. The primary objective of the object explorer is to allow object to be searched by their name. The object explorer contains two panels: the top panel and the bottom panel. The top panel presents the format hierarchy in terms of layers and composite objects. The bottom panel displays the children objects of selected component from the top panel. The top panel also allows quick manipulation of layer visibility and ability to change the current active layer. The bottom object search panel allows object to be searched by their name. In addition to this, the object type filter allows objects to be filtered by their type. The object type filter also provides statistics regarding how many objects of a particular object types are present. The column based list view in the bottom panel allows objects to be sorted by name and column. In addition to this, when the object is selected on the list the corresponding object gets selected on the format designer and the Sammi pan command is sent to pan the object to the top-left corner of the format designer surface. When working with large format containing many small objects, it is sometimes difficult to figure out where the selected object is. In this situation, one can zoom into the format and then use the list view to select the object and format will pan to make it easier to see the object. Besides selecting an object via the list view, the object property dialogs can also be accessed by double clicking on the object in the list view. The property dialog can be used to modify the object. The object explorer panel also allows objects within the group/composite to be selected and manipulated. This feature provides a mean by which the object within the group can be modified without having to perform ungroup and then regroup again.

      The Role of Scripting: The object explorer functionalities are implemented in $SAMMI/data_fe/fmt_object_explorer.py file. The file uses the Sammi object model in the som module and the fe module to access various format attributes for the format being edited.

  • Test Automation

    The som module provides a way to query the format attributes and receive callback when a ddo’s runtime data buffer is updated. By using this information, one can automate varoious test scenarios for a given format. The examples section provides some illustration of how to automate Sammi format testing.

  • Creating Objects Programmatically

    The scripting feature can allow components in Sammi formats to be created programmatically. The example illustrates how shapes can programmatically be added to a format in the SAMMI studio. This allows importer utilities to be created for various types of shape formats from other applications such as AutoCAD.

  • Format Debug Utility

    The example illustrates how the format debug utility can be developed using Sammi scripting. The purpose of the utility is to monitor and debug format data updates at runtime.

 

Scripting Examples

 

  • Example 1

    Overview:         This example illustrates how scripting can be used at runtime to process command and gain access to format properties for currently active formats at runtime.

    Execution Steps:

    1. Start Sammi runtime (i.e. start_sammi)
    2. Logon using the ‘demopro’ user id
    3. Execute ‘execute-script example1’ command in the command window.

     

    Script Code:$SAMMI/data_demo/example1.py

    # This example show how the the methods from the rte module can be used to
    # to control and query the runtime functionalities. In addition to this, the
    # sammi format object model from the som module is used to access format properties.
    #
    import rte

    #Displays various format properties
    def show_format_properties(fmt):
    rte.print_msg(“Name: %s”%fmt.Name)
    rte.print_msg(“Title: %s”%fmt.Title)
    rte.print_msg(“Directory Path: %s”%fmt.DirPath)
    rte.print_msg(“Zoom Value: %d”%fmt.ZoomFactor)

    rte.print_msg(“————-Output from Example 1———————–“)

    #sends sammi command to the sammi runtime command processor
    rte.send_command(“add-window about-win”)
    rte.send_command(“add-window ndbm”)

    #retreives the list of currently active formats in sammi runtime.
    fmt_list = rte.get_active_formats()

    rte.print_msg(“Total active formats: %d” % len(fmt_list))

    cnt=1
    #Print few format properties for each active format
    for fmt in fmt_list:
    rte.print_msg(“************ %d *************”%cnt)
    show_format_properties(fmt)
    cnt=cnt+1

    rte.print_msg(“———————————————————“)

    Console Output:
















  • Example 2:

    Overview:       This example illustrates how Sammi object model can be utilized at Sammi runtime to get component information for a specific format.

    Execution Steps:

    1. Start Sammi runtime (i.e. start_sammi)
    2. Logon using the ‘demopro’ user id
    3. Execute ‘execute-script example2’ command in the command window.

     

    Script Code:$SAMMI/data_demo/example2.py




    import rte
    import som

    # Searches for the particular format name in the list of currently active formats and if
    # the format name matches, the method returns the format instance.
    # Parameters:
    # fmt_name – string : the format name that needs to be searched for in the active format list
    # Return type: Format
    def get_active_format(fmt_name):
    fmt_list = rte.get_active_formats()
    for fmt in fmt_list:
    if(fmt.Name == fmt_name):
    return fmt
    return None

    # Updates the component type dictionary with the object count.
    # Parameters:
    # comp – CompositeObj : the composite object instance from which to get the list of display objects
    # dict_info – dict : the dictionary instance which will be updated with object count.
    def get_obj_type_info(comp,dict_info):
    dpy_objects = comp.getDisplayObjects()
    for dpy_obj in dpy_objects:
    if ( dpy_obj.DisplayObjTypeName in dict_info ):
    dict_info[dpy_obj.DisplayObjTypeName] = dict_info[dpy_obj.DisplayObjTypeName] + 1
    else:
    dict_info[dpy_obj.DisplayObjTypeName] = 1

    # if a composite object is present then loop into the instance process its children.
    if ( dpy_obj.DisplayObjType == som.COMPOSITE):
    get_obj_type_info(dpy_obj,dict_info)

    # Prints component count by component type for the given format instance
    # Parameters:
    # fmt – Format : the format instance for which the component stats should be printed
    def print_obj_count_by_type(fmt):
    dict_info = dict()
    layers = fmt.getLayers()

    for layer in layers:
    get_obj_type_info(layer,dict_info)

    rte.print_msg(“Components Count by Type:\n”)
    obj_types = dict_info.keys()
    for obj_type in obj_types:
    rte.print_msg(“%-15s = %s” %(obj_type,dict_info[obj_type]))

    rte.print_msg(“————-Output from Example 2———————–“)

    #add the about-win format using the add-window command.
    rte.send_command(“add-window about-win”)

    #get the about-win format instance.
    fmt = get_active_format(“about-win”)

    #print component stats
    if (fmt):
    print_obj_count_by_type(fmt)

    rte.print_msg(“———————————————————“)

    Console Output:

    Image = 1
    VectorText = 16
    Button = 1
    Rectangle = 1
    TextBox = 5
    ———————————————————

  • Example 3:

    Overview:       This example shows how layer information for a particular format can be accessed via scripting. The example uses the region_demo3 format.

    Execution Steps:

    1. Start Sammi runtime (i.e. start_sammi)
    2. Logon using the ‘demopro’ user id
    3. Execute ‘execute-script example3’ command in the command window.

     

    Script Code:$SAMMI/data_demo/example3.py



    # Searches for the particular format name in the list of currently active formats and if
    # the format name matches, the method returns the format instance.
    # Parameters:
    # fmt_name – string : the format name that needs to be searched for in the active format list
    # Return type: Format
    def get_active_format(fmt_name):
    fmt_list = rte.get_active_formats()
    for fmt in fmt_list:
    if(fmt.Name == fmt_name):
    return fmt
    return None

    # Prints layer infomation related to given format instance.
    # Parameters:
    # fmt – Format : the format instance for which layer information needs to be printed.
    def print_layers_info(fmt):
    layers = fmt.getLayers()
    rte.print_msg(“%-12s | %-15s | %-15s | %-15s | %-15s”%(“Layer Name”,”Visibility”,”Declutter”,”Min Declutter”,”Max Declutter”))
    rte.print_msg(“————————————————————————————“)
    for layer in layers:
    rte.print_msg(“%-12s | %-15s | %-15s | %-15s | %-15s”%(layer.Name,layer.Visibility,layer.Declutter,layer.MinDeclutter,layer.MaxDeclutter))

    rte.print_msg(“————-Output from Example 3———————–\n”)

    rte.send_command(“add-window region_demo3”)

    fmt = get_active_format(“region_demo3”)
    if (fmt):
    print_layers_info(fmt)

    rte.print_msg(“\n———————————————————“)

    Console Output:

    Layer Name | Visibility | Declutter | Min Declutter | Max Declutter
    ————————————————————————————
    Layer 0 | True | True | 25 | 1000
    Layer 1 | True | True | 60 | 1000
    Layer 2 | True | True | 40 | 1000
    Layer 3 | True | False | -1 | -1
    Layer 4 | True | True | 60 | 1000
    Regions ABCD | True | False | -1 | -1
    Layer 6 | True | False | -1 | -1

    ———————————————————

  • Example 4:

    Overview:       This example illustrates how ddo properties such as name, location, size, data access information can be accessed using the Sammi object model for a particular format. The example uses the ‘ndbm’ format.

    Execution Steps:

    1. Start sammi runtime (i.e. start_sammi)
    2. Logon using the ‘demopro’ user id
    3. Execute ‘execute-script example4’ command in the command window.

     

    Script Code:$SAMMI/data_demo/example4.py




    # Searches for the particular format name in the list of currently active formats and if
    # the format name matches, the method returns the format instance.
    # Parameters:
    # fmt_name – string : the format name that needs to be searched for in the active format list
    # Return type: Format
    def get_active_format(fmt_name):
    fmt_list = rte.get_active_formats()
    for fmt in fmt_list:
    if(fmt.Name == fmt_name):
    return fmt
    return None

    # Prints ddo specific properties
    # Parametes:
    # ddo – Ddo : the ddo instance for which the properties needs to be printed
    def print_ddo_info(ddo):

    #Print basic ddo info.
    rte.print_msg(“Type = %s, Name = %s” % (ddo.DisplayObjTypeName,ddo.Name))
    rte.print_msg(“Location = (%4d,%4d), Size = (%4d,%4d)” % (ddo.X,ddo.Y,ddo.Width,ddo.Height))

    #Gets the data confguration properties associated with the ddo.
    dat = ddo.getDataConfig()

    #Check the data config type.
    if (dat.DataConfigType == som.DA_NONE):
    rte.print_msg(“Data Access Type: None”)
    elif (dat.DataConfigType == som.DA_LOCAL):
    local_info = dat.getLocalData()
    rte.print_msg(“Data Access Type: Local, NumPoints = %d”%local_info.NumPoints)
    elif (dat.DataConfigType == som.DA_UNIVERSAL):
    uni_info = dat.getUniversalData()
    rte.print_msg(“Data Access Type: Universal, LogicalServer = %s, ReadKey = ‘%s’, WriteKey = ‘%s'”%(uni_info.LogicalServer,uni_info.ReadKey,uni_info.WriteKey))

    # Prints ddo information for a given composite object
    # Parameters
    # comp – CompositeObj : the composite object instance which needs to be queried to get ddos.
    def print_comp_info(comp):
    dpy_objs = comp.getDisplayObjects()
    for dpy_obj in dpy_objs:
    if dpy_obj.IsDdo:
    print_ddo_info(dpy_obj)
    rte.print_msg(“**********************************************************************************************”)
    if dpy_obj.DisplayObjType == som.COMPOSITE:
    print_comp_info(dpy_obj)
    #
    # Print ddo related info for the given format instance
    # Parameters:
    # fmt – Format : the format instance for which the ddo info needs to be printed
    def print_format_info(fmt):
    layers = fmt.getLayers()
    for layer in layers:
    print_comp_info(layer)

    rte.print_msg(“————-Output from Example 4———————–“)
    rte.send_command(“add-window ndbm”)

    fmt = get_active_format(“ndbm”)
    if (fmt):
    print_format_info(fmt)
    rte.print_msg(“———————————————————“)

     

    Console Output:




























































































































  • Example 5:

    Overview:       This example illustrates how shape information can be obtained from a particular format. The example uses the ‘fast_dobj’ format to periodically query the shape properties. Since the fast_dobj format controls these shapes using the dobj, the shape properties are dynamically updated. The example illustrates that the exposed Sammi object model is able to provide status of the shape objects in real-time.

    Execution Steps:

    1. Start sammi runtime (i.e. start_sammi)
    2. Logon using the ‘demopro’ user id
    3. Execute ‘execute-script example5’ command in the command window.

     

    Script Code:$SAMMI/data_demo/example5.py


    import rte
    import som

    timer_val = 2000 #2 seconds

    # Searches for the particular format name in the list of currently active formats and if
    # the format name matches, the method returns the format instance.
    # Parameters:
    # fmt_name – string : the format name that needs to be searched for in the active format list
    # Return type: Format
    def get_active_format(fmt_name):
    fmt_list = rte.get_active_formats()
    for fmt in fmt_list:
    if(fmt.Name == fmt_name):
    return fmt
    return None

    #
    # Given the shape instance, this method prints some shape properties.
    # Parameters:
    # shape – Shape : the shape instance for which the property info. needs to be printed
    def print_shape_info(shape):
    clr_name = som.get_color_name_from_index(shape.ForeColor)
    rte.print_msg(“%-15s | (%4d,%4d) | (%4d,%4d) | %-15s”%(shape.DisplayObjTypeName,shape.X,shape.Y,shape.Width,shape.Height,clr_name))

    # Prints ddo information for a given composite object
    # Parameters
    # comp – CompositeObj : the composite object instance which needs to be queried to get ddos.
    def print_comp_info(comp):
    dpy_objs = comp.getDisplayObjects()
    for dpy_obj in dpy_objs:
    if not (dpy_obj.IsDdo) and not(dpy_obj.DisplayObjType == som.COMPOSITE):
    print_shape_info(dpy_obj)
    if dpy_obj.DisplayObjType == som.COMPOSITE:
    print_comp_info(dpy_obj)

    #
    # Print shape related info for the given format instance
    # Parameters:
    # fmt – Format : the format instance for which the shape info needs to be printed
    def print_format_info(fmt):
    layers = fmt.getLayers()
    rte.print_msg(“%-15s | %-11s | %-11s | %-15s”%(“Shape Type”,”Location”,”Size”,”Color”))
    rte.print_msg(“———————————————————-“)
    for layer in layers:
    print_comp_info(layer)
    rte.print_msg(“**********************************************************************************************”)

    def timer_cb(data):
    fmt = get_active_format(“fast_dobj”)
    if(fmt):
    print_format_info(fmt)
    rte.add_timer(timer_val,timer_cb,”fast_dobj”)

    rte.print_msg(“————-Output from Example 5———————–“)
    rte.send_command(“add-window fast_dobj”)

    rte.add_timer(timer_val,timer_cb,”fast_dobj”)
    rte.print_msg(“———————————————————“)

     

    Console Output:


















  • Example 6:

    Overview:       This example illustrates how Sammi scripting can be used to perform test automation for Sammi formats.

    Execution Steps:

    1. Start Sammi runtime (i.e. start_sammi)
    2. Logon using the ‘demopro’ user id
    3. Execute ‘execute-script example6’ command in the command window.

     

    Script Code:$SAMMI/data_demo/example6.py






    # Searches for the particular format name in the list of currently active formats and if
    # the format name matches, the method returns the format instance.
    # Parameters:
    # fmt_name – string : the format name that needs to be searched for in the active format list
    # Return type: Format
    def get_active_format(fmt_name):
    fmt_list = rte.get_active_formats()
    for fmt in fmt_list:
    if(fmt.Name == fmt_name):
    return fmt
    return None

    # Return true if the ddo’s data buffer value matches with the expected value. Otherwise false is returned.
    # Parameters:
    # fmt – Format : the format instance in which to search the ddo
    # ddo_name – string : the ddo name for which the expected value needs to be compared
    # expected_val – float : the value that is expected in the ddo’s data buffer
    # Return type : bool
    def check_ddo_data(fmt,ddo_name,expected_val):
    if (fmt):
    ddo = fmt.getDisplayObjByName(ddo_name)
    if (ddo):
    ds = ddo.getData()
    table = ds.Tables[0]
    rows = table.Rows[0]
    ddo_val = int(math.floor(float(rows.Values[0])))
    if ( ddo_val == expected_val ):
    return True
    return False

    # This method is called whenever the ndbm format is updated with data value update from the peer.
    # The method is responsible for checking to see if the ddo update occurred with the expected value.
    def fmt_data_update_cb(ddo):
    global ddo_update_list

    # only check for ddo update that we are interested in.
    if (ddo.Name in ddo_update_list.keys()):
    fmt = get_active_format(“ndbm”)
    vals = ddo_update_list[ddo.Name]
    expected_val = vals[0]
    if (check_ddo_data(fmt,ddo.Name,expected_val)):
    rte.print_msg(“The ddo ‘%s’ was correctly updated with data value %s as expected.”%(ddo.Name,expected_val))
    else:
    rte.print_msg(“The ddo ‘%s’ did not match with expectated data value %s.”%(ddo.Name,expected_val))

    #ddo check was complete, remove it from the list.
    del ddo_update_list[ddo.Name]

    # This method is responsible for generating random data for the specified ddo. It also adds the target ddo
    # to the ddo_update_list so that it can be later checked to see if it received expected data value.
    # Parameters:
    # data – list : the first value in the list is a ddo name which will be updated with random data.
    # the second value in the list is the target ddo name
    def update_data(data):
    fmt = get_active_format(“ndbm”)
    if (fmt):
    ddo1_name = data[0]
    ddo2_name = data[1]
    val=int(random.random()*1000)

    #the following command causes sammi to generate WRITE event to the ndbm server. This in turn causes
    #the server to update its data value and generate data update event on the next poll cycle. For test automation,
    #the peer may need to be modified so that it can deal with test specific commands.
    rte.send_command(“exe-com 0 ndbm %s e %d”%(ddo1_name,val))
    rte.print_msg(“Updated ddo ‘%s’ with data value %s”%(ddo1_name,val))

    args = list()
    args.append(val)
    args.append(datetime.datetime.now())
    ddo_update_list[ddo2_name]=args

    # This method is responsible to see if any of the ddo data update did not occur in expected time interval.
    # The method completes the test by closing the ndbm format.
    def test_complete_check(data):
    global ddo_update_list

    for ddo_name in ddo_update_list.keys():
    rte.print_msg(“The ddo ‘%s’ did not update in the given time period.”%ddo_name)

    ddo_update_list.clear()
    rte.send_command(“delete-window ndbm”)
    rte.print_msg(“———————————————————“)

    rte.print_msg(“————-Output from Example 6———————–“)
    rte.send_command(“add-window ndbm”)

    ddo_update_list = dict()
    fmt = get_active_format(“ndbm”)
    if (fmt):
    fmt.addDataUpdateCallback(fmt_data_update_cb)

    rte.add_timer(1000,update_data,[“long0″,”long3”])
    rte.add_timer(1000,update_data,[“short0″,”short3”])
    rte.add_timer(1000,update_data,[“float0″,”float3”])
    rte.add_timer(1000,update_data,[“double0″,”double3”])

    rte.add_timer(15000,test_complete_check,None)

    Console Output:








  • Example 7:

    Overview:       This example illustrates how interface for the dobj ddo can be used to access it properties. This information can be used to perform test automation.

    Execution Steps:

    1. Start Sammi runtime (i.e. start_sammi)
    2. Logon using the ‘demopro’ user id
    3. Execute ‘execute-script example7’ command in the command window.

     

    Script Code:$SAMMI/data_demo/example7.py





    # Searches for the particular format name in the list of currently active formats and if
    # the format name matches, the method returns the format instance.
    # Parameters:
    # fmt_name – string : the format name that needs to be searched for in the active format list
    # Return type: Format
    def get_active_format(fmt_name):
    fmt_list = rte.get_active_formats()
    for fmt in fmt_list:
    if (fmt.Name == fmt_name):
    return fmt
    return None

    # The callback method that will be called whenever a ddo data update occurs.
    # Parameters:
    # ddo – Ddo : the ddo instance that has been updated.
    def fmt_data_update_cb(ddo):
    if (ddo.DisplayObjType == som.DOBJ_DDO):
    #Gets the objects controlled by the dobj object
    dobj_objects = ddo.getObjects()
    #print dobj properties
    rte.print_msg(“dobj (name = %s, id = %s, location = (%d,%d)) was updated:” %(ddo.Name,ddo.Id,ddo.X,ddo.Y))
    for obj in dobj_objects:
    #print dobj controlled object properties
    rte.print_msg(” display obj: type = %-12s, id = %-4d, forecolor = %-15s”%(obj.DisplayObjTypeName,obj.Id,som.get_color_name_from_index(obj.ForeColor)))

    #Adds the ‘trans5_40’ format to the runtime.
    rte.send_command(“add-window trans5_40”)

    fmt = get_active_format(“trans5_40”)
    if(fmt):
    fmt.addDataUpdateCallback(fmt_data_update_cb)

    Console Output:




























  • Example 8:

    Overview:       This example illustrates how interface for the vector symbol ddo can be used to access it properties. This information can be used to perform test automation.

    Execution Steps:

    1. Start Sammi runtime (i.e. start_sammi)
    2. Logon using the ‘demopro’ user id
    3. Execute ‘execute-script example8’ command in the command window.

     

    Script Code:$SAMMI/data_demo/example8.py





    # Searches for the particular format name in the list of currently active formats and if
    # the format name matches, the method returns the format instance.
    # Parameters:
    # fmt_name – string : the format name that needs to be searched for in the active format list
    # Return type: Format
    def get_active_format(fmt_name):
    fmt_list = rte.get_active_formats()
    for fmt in fmt_list:
    if (fmt.Name == fmt_name):
    return fmt
    return None

    #This callback will be called whenever a ddo receives a data update on the format.
    # Parameters:
    # ddo – Ddo : the ddo instance that has been updated.
    def fmt_data_update_cb(ddo):
    #In this example, we are only interested in the vector symbol ddo.
    if (ddo.DisplayObjType == som.VECTOR_SYMBOL_DDO):
    #Get the table and symbol name associated with the vector symbol ddo.
    table_name = ddo.TableName
    symbol_name = ddo.getCurrentSymbolName()
    rte.print_msg(“vector symbol: table name = %s, symbol name = %s:” %(table_name,symbol_name))

    #Add the ‘vector_demo3’ format at runtime.
    rte.send_command(“add-window vector_demo3”)

    fmt = get_active_format(“vector_demo3”)
    if(fmt):
    #register for the data update event for the format.
    fmt.addDataUpdateCallback(fmt_data_update_cb)

    Console Output:



























  • Example 9:

    Overview:       This example illustrates how interface for the bitmap symbol ddo can be used to access it properties. This information can be used to perform test automation.

    Execution Steps:

    1. Start Sammi runtime (i.e. start_sammi)
    2. Logon using the ‘demopro’ user id
    3. Execute ‘execute-script example9’ command in the command window.

     

    Script Code:$SAMMI/data_demo/example9.py





    # Searches for the particular format name in the list of currently active formats and if
    # the format name matches, the method returns the format instance.
    # Parameters:
    # fmt_name – string : the format name that needs to be searched for in the active format list
    # Return type: Format
    def get_active_format(fmt_name):
    fmt_list = rte.get_active_formats()
    for fmt in fmt_list:
    if (fmt.Name == fmt_name):
    return fmt
    return None

    #This callback will be called whenever a ddo receives a data update on the format.
    # Parameters:
    # ddo – Ddo : the ddo instance that has been updated.
    def fmt_data_update_cb(ddo):
    #only process the bitmap symbol ddo
    if (ddo.DisplayObjType == som.BITMAP_SYMBOL_DDO):
    #Get the table and symbol name associated with the bitmap symbol ddo.
    table_name = ddo.TableName
    symbol_name = ddo.getCurrentSymbolName()
    rte.print_msg(“bitmap symbol: table name = %s, symbol name = %s:” %(table_name,symbol_name))

    #Add the ‘symbol_demo3’ format at runtime.
    rte.send_command(“add-window symbol_demo3”)

    fmt = get_active_format(“symbol_demo3”)
    if(fmt):
    #register for the data update event with the format.
    fmt.addDataUpdateCallback(fmt_data_update_cb)

    Console Output:
















  • Example 10:

    Overview:       This example illustrates how interface for the object icon ddo can be used to access it properties. This information can be used to perform test automation.

    Execution Steps:

    1. Start Sammi runtime (i.e. start_sammi)
    2. Logon using the ‘demopro’ user id
    3. Execute ‘execute-script example10’ command in the command window.

     

    Script Code:$SAMMI/data_demo/example10.py





    # Searches for the particular format name in the list of currently active formats and if
    # the format name matches, the method returns the format instance.
    # Parameters:
    # fmt_name – string : the format name that needs to be searched for in the active format list
    # Return type: Format
    def get_active_format(fmt_name):
    fmt_list = rte.get_active_formats()
    for fmt in fmt_list:
    if (fmt.Name == fmt_name):
    return fmt
    return None

    #This callback will be called whenever a ddo receives a data update on the format.
    # Parameters:
    # ddo – Ddo : the ddo instance that has been updated.
    def fmt_data_update_cb(ddo):
    #only process the object icon ddo updates
    if (ddo.DisplayObjType == som.OBJ_ICON_DDO):
    #Get the table and symbol name associated with the ddo.
    table_name = ddo.TableName
    symbol_name = ddo.getCurrentSymbolName()
    rte.print_msg(“object icon: table name = %s , symbol name = %s:” %(table_name,symbol_name))

    #Adds the the ‘objicon_demo3’ format at runtime.
    rte.send_command(“add-window objicon_demo3”)

    fmt = get_active_format(“objicon_demo3”)
    if(fmt):
    #Add data update callback to the format.
    fmt.addDataUpdateCallback(fmt_data_update_cb)

    Console Output:























  • Example 11:

    Overview:       This example illustrates how interface for the text symbol ddo can be used to access it properties. This information can be used to perform test automation.

    Execution Steps:

    1. Start Sammi runtime (i.e. start_sammi)
    2. Logon using the ‘demopro’ user id
    3. Execute ‘execute-script example11’ command in the command window.

     

    Script Code:$SAMMI/data_demo/example11.py





    # Searches for the particular format name in the list of currently active formats and if
    # the format name matches, the method returns the format instance.
    # Parameters:
    # fmt_name – string : the format name that needs to be searched for in the active format list
    # Return type: Format
    def get_active_format(fmt_name):
    fmt_list = rte.get_active_formats()
    for fmt in fmt_list:
    if (fmt.Name == fmt_name):
    return fmt
    return None

    #This callback will be called whenever a ddo receives a data update on the format.
    # Parameters:
    # ddo – Ddo : the ddo instance that has been updated.
    def fmt_data_update_cb(ddo):
    #only process the text symbol ddo.
    if (ddo.DisplayObjType == som.TEXT_SYMBOL_DDO):
    #Get the table and symbol name associated with the ddo.
    table_name = ddo.TableName
    symbol_name = ddo.getCurrentSymbolName()
    rte.print_msg(“text symbol: table name = %s , symbol name = %s” %(table_name,symbol_name))

    #Add the ‘texttable_demo3’ format at runtime.
    rte.send_command(“add-window texttable_demo3”)

    fmt = get_active_format(“texttable_demo3”)
    if(fmt):
    #Add the data update event for the format.
    fmt.addDataUpdateCallback(fmt_data_update_cb)

    Console Output:



















  • Example 12:

    Overview:       This example illustrates how shape animation can be performed using scripting in Sammi. The example adds the ‘trans3_40’ format at runtime and changes the foreground color for polygons and lines at specific timer interval.

    Execution Steps:

    1. Start Sammi runtime (i.e. start_sammi)
    2. Logon using the ‘demopro’ user id
    3. Execute ‘execute-script example12’ command in the command window.

     

    Script Code:$SAMMI/data_demo/example12.py





    # Searches for the particular format name in the list of currently active formats and if
    # the format name matches, the method returns the format instance.
    # Parameters:
    # fmt_name – string : the format name that needs to be searched for in the active format list
    # Return type: Format
    def get_active_format(fmt_name):
    fmt_list = rte.get_active_formats()
    for fmt in fmt_list:
    if (fmt.Name == fmt_name):
    return fmt
    return None

    # Perfroms shape color changes at specific timer interval using
    # randomly generated color index value.
    def fmt_timer_cb(data):
    fmt = get_active_format(data)
    if (fmt):
    num = int(random.random() * 100) #generate color index value between 0 – 100
    num2 = int(random.random() * 100) #generate color index value between 0 – 100
    lyrs = fmt.getLayers()
    for lyr in lyrs:
    dpy_objects = lyr.getDisplayObjects()
    for dpy in dpy_objects:
    #Use the randomly generated color index value to change
    #line’s foreground color
    if (dpy.DisplayObjType == som.POLYLINE):
    dpy.ForeColor = num
    dpy.repaint()
    #Use the randomly generated color index value to change
    #polygon’s foreground color
    if (dpy.DisplayObjType == som.POLYGON):
    dpy.ForeColor = num2
    dpy.repaint()

    #register timer for every 3 sec.
    rte.add_timer(3000,fmt_timer_cb,data)

    rte.send_command(“add-window trans3_40”)
    fmt_timer_cb(“trans3_40”)

     

  • Creating Shapes using Script:

    Overview:       This example illustrates how scripting can be used to programmatically create shapes in Sammi studio. This feature can be utilized to save significant time in format creation. It can also be used to create script that imports drawings from other applications such as AutoCAD.

    Execution Steps:

    1. Start Sammi studio(i.e. start_studio)
    2. Logon using the ‘root’ user id
    3. Create a new format.
    4. Go to View->Command Window to show the command window.
    5. Execute ‘execute-script create_shapes’ command in the command window.

     

    Script Code:$SAMMI/data_demo/create_shapes.py




    #Creates various shape objects on the given display and layer
    #Parameters:
    # fmt – Format : the format instance in which to create new shapes
    # active_lyr – LayerObj : the layer object instance in which to add new shapes.
    def create_shapes(fmt,active_lyr):

    #Creates vector text– som.createVectorText(fmt,text,x,y)
    text = som.createVectorText(fmt,”Example of Creating Shapes using Script”,200,20);
    text.ForeColor=som.get_color_index_from_rgb(0,0,0)
    text.FillStyle=som.FS_SOLID
    active_lyr.insertObjectInBack(text)
    text.repaint()

    #Creates rectangle — som.createRectangle(fmt,x,y,width,height)
    rect = som.createRectangle(fmt,10,50,100,80)
    rect.ForeColor=som.get_color_index_from_rgb(255,0,0)
    rect.FillStyle=som.FS_NO_FILL
    active_lyr.insertObjectInBack(rect)
    rect.repaint()

    #Creates line — som.createLine(fmt,x1,y1,x2,y2)
    line = som.createLine(fmt,10,150,100,250)
    line.ForeColor=som.get_color_index_from_rgb(127,38,200)
    line.ForwardArrow=True
    line.BackwardArrow=True
    line.LineThickness=6
    active_lyr.insertObjectInBack(line)
    line.repaint()
    pts = line.Points
    rte.print_msg(“line pts = “)
    for pt in pts:
    rte.print_msg(” (%d,%d) “%(pt.X,pt.Y))

    #Creates polyline — som.createPolyLine(fmt,pt_list)
    lst2 = list()
    lst2.append(som.Point(10,280))
    lst2.append(som.Point(100,300))
    lst2.append(som.Point(150,350))
    lst2.append(som.Point(50,380))
    pline = som.createPolyLine(fmt,lst2)
    pline.ForeColor=som.get_color_index_from_rgb(0,255,0)
    pline.LineThickness=2
    pline.LineStyle= som.LS_DASH
    pline.LineDash= 5
    active_lyr.insertObjectInBack(pline)
    pline.ForwardArrow=True
    pline.BackwardArrow=True
    pline.FillStyle=som.FS_NO_FILL
    pline.repaint()
    pts = pline.Points
    rte.print_msg(“poly line pts = “)
    for pt in pts:
    rte.print_msg(” (%d,%d) “%(pt.X,pt.Y))

    #Creates polygon — som.createPolygon(fmt,pt_list)
    lst3 = list()
    lst3.append(som.Point(150,50))
    lst3.append(som.Point(370,60))
    lst3.append(som.Point(250,100))
    polygon= som.createPolygon(fmt,lst3)
    polygon.ForeColor=som.get_color_index_from_rgb(0,0,255)
    polygon.BackColor=som.get_color_index_from_rgb(127,127,127)
    polygon.FillStyle=som.FS_OPAQUE_STIPPLED
    polygon.StipplePattern=5
    active_lyr.insertObjectInBack(polygon)
    polygon.repaint()
    pts = polygon.Points
    rte.print_msg(“polygon pts = “)
    for pt in pts:
    rte.print_msg(” (%d,%d) “%(pt.X,pt.Y))

    #Creates open spline — som.createOpenSpline(fmt,pt_list)
    lst4 = list()
    lst4.append(som.Point(200,150))
    lst4.append(som.Point(390,170))
    lst4.append(som.Point(300,230))
    lst4.append(som.Point(230,240))
    spline= som.createOpenSpline(fmt,lst4)
    spline.ForeColor=som.get_color_index_from_name(“orange”)
    active_lyr.insertObjectInBack(spline)
    spline.ForwardArrow=True
    spline.BackwardArrow=True
    spline.LineThickness=3
    spline.repaint()
    pts = spline.Points
    rte.print_msg(“open spline pts = “)
    for pt in pts:
    rte.print_msg(” (%d,%d) “%(pt.X,pt.Y))

    #Creates closed spline — som.createClosedSpline(fmt,pt_list)
    lst5 = list()
    for pt in lst4:
    lst5.append(som.Point(pt.X,pt.Y+150))
    spline= som.createClosedSpline(fmt,lst5)
    spline.ForeColor=som.get_color_index_from_name(“cyan”)
    spline.FillStyle=som.FS_OPAQUE_STIPPLED
    spline.StipplePattern=10
    spline.Outline = True
    spline.LineThickness = 5
    spline.OutlineColor = som.get_color_index_from_rgb(128,255,255)
    active_lyr.insertObjectInBack(spline)
    spline.repaint()
    pts = spline.Points
    rte.print_msg(“closed spline pts = “)
    for pt in pts:
    rte.print_msg(” (%d,%d) “%(pt.X,pt.Y))

    #Creates ellipse — som.createEllipse(fmt,center_x,center_y,radius_x,radius_y)
    ellipse = som.createEllipse(fmt,470,100,100,40)
    ellipse.ForeColor=som.get_color_index_from_name(“yellow”)
    ellipse.OutlineColor=som.get_color_index_from_rgb(0,0,255)
    ellipse.FillStyle=som.FS_SOLID
    ellipse.LineThickness=5
    ellipse.Outline = True
    active_lyr.insertObjectInBack(ellipse)
    ellipse.repaint()
    pt = ellipse.Center
    rte.print_msg(“ellipse center = (%d,%d) ” %(pt.X,pt.Y))
    pt = ellipse.Radii
    rte.print_msg(“ellipse radii (%d,%d) ” %(pt.X,pt.Y))
    rte.print_msg(“ellipse fore color = %s ” % som.get_color_name_from_index(ellipse.ForeColor))

    #Creates arc — som.createArc(fmt,center_x,center_y,radius_x,radius_y,start_angle,sweep_angle)
    arc= som.createArc(fmt,470,250,80,60,0,130)
    arc.ForeColor=som.get_color_index_from_rgb(0,120,230)
    arc.FillStyle=som.FS_SOLID
    active_lyr.insertObjectInBack(arc)
    arc.repaint()
    pt = arc.Center
    rte.print_msg(“arc center = (%d,%d) ” %(pt.X,pt.Y))
    pt = arc.Radii
    rte.print_msg(“arc radii (%d,%d) ” %(pt.X,pt.Y))
    rte.print_msg(“arc angles = (%d,%d) ” %(arc.StartAngle,arc.SweepAngle))

    #Creates frame — som.createFrame(fmt,x,y,width,height)
    frame = som.createFrame(fmt,450,300,130,80)
    frame.ForeColor=som.get_color_index_from_rgb(0,120,230)
    frame.Fill=True
    frame.BorderWidth=10
    frame.BorderType=som.BORDER_ETCHED_IN
    active_lyr.insertObjectInBack(frame)
    frame.repaint()

    #creates image — som.createImage(fmt,file_name,file_type,x,y,width,height)
    img= som.createImage(fmt,’alarm’,som.IMAGE_TYPE_XBM,140,215,50,50)
    img.ForeColor=som.get_color_index_from_name(“white”)
    img.BackColor=som.get_color_index_from_name(“blue”)
    active_lyr.insertObjectInBack(img)
    img.repaint()
    rte.print_msg(“img name = %s” % img.FileName)
    rte.print_msg(“img file type = %s” % img.ImageType)

    rte.print_msg(“————————-Create Shapes—————————“)

    #Get the currently active format instance in FE.
    fmt = fe.get_active_format()

    #Get the currently active layer instance.
    active_lyr = fe.get_active_layer()

    if (not fmt):
    rte.print_msg(“Unable to find active format.”)
    elif (not active_lyr):
    rte.print_msg(“Unable to locate active layer instance.”)
    else:
    create_shapes(fmt,active_lyr)

    rte.print_msg(“—————————————————————–“)

    Console Output:
































    Output:

  • SDI in Runtime

    Overview:       This example illustrates how scripting and qt based PySide library can be used for creating SDI (Single Document Interface) using Sammi formats. The example adds a button panel at the top and alarm panel at the bottom. The middle panel is used for displaying sammi formats that are displayed based on button selected on the button panel.

    Execution Steps:

    1. Start Sammi runtime using start_sammi script
    2. Logon using the ‘demopro’ user id
    3. Execute ‘execute-script rte_sdi’ command in the command window.

     

    Script Code:$SAMMI/data_demo/rte_sdi.py

    Output:

  • Format Debug Utility

    Overview:       This example illustrates how the Sammi object model and scripting can be used to create a utility for debugging data updates for a format at runtime. The example uses PySide library for creating MDI interface and the exposed Sammi interfaces to collect format data at runtime.

    Execution Steps:

    1. Start Sammi runtime using start_sammi script
    2. Logon using the ‘demopro’ user id
    3. Execute ‘add-window ndbm’ command in the command window to add a format.
    4. Execute ‘execute-script format_debug_util’ command in the command window to display the utility application.
    5. Click on the ‘Add-Format’ button to see list of active formats.
    6. Select the ‘ndbm’ format.

     

    Script Code:$SAMMI/data_demo/format_debug_util.py

    Output: