Python Coding

 

Overview

Sammi 7 provides 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 python script interpreter and exposing various Sammi capabilities through python interfaces, Sammi 7 is provided with a set of new features. These new features improve different phases of the Sammi application development process, such as designing and creating displays, automating display testing, verifying pre-built displays, monitoring and debugging display data updates at runtime, etc. The sections Applications of Scripting and Roadmap provide a glimpse into the type of capabilities that can be achieved by leveraging these scripting interfaces in Sammi.

Sammi Python Interfaces

The interfaces described below are used to interface with Sammi at Runtime and design time.
  • Sammi Object Model (SOM)The SOM module is a critical component for exposing Sammi's object model to python scripts. This module can be used with the Sammi Runtime, at design time and even with stand-alone python scripts. Although, the primary purpose of this module is to provide access to attributes associated with Sammi objects such as: displays, layer, shape, DDOs, 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. It also provides a way to get a list of currently active plays 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 command was added for executing python scripts within Sammi. Just as the add-window command searches the folders specified in the SAM2_DATAFILE environment varaible for adding a display, the execute-script command will also use the SAM2_DATAFILE to search for the python script to execute.

Applications of Scripting

  • Sammi Studio

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

      Key Features: The MDI interface, or multiple document interface, in Studio provides a container environment for the IDE. It is responsible for managing menus, toolbars, panels, dialogs, and mdi subwindows. It also acts as a controller for delegating specific responsibilityies/events from the displaydesigner 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 menus and toolbars in Studio allows users to manage the display 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 display designer surface and menu/toolbar primarily occur using Sammi commands. The send_command method from the RTE module is used to execute display 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 objects on the display designer surface. The interaction between the displaydesigner surface and menu/toolbar also primarily occurs 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 display 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 a Sammi project based on its file type.  The search box in the panel allows easy searches 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 dragged and dropped to the display designer surface. The project explorer also provides a UI to load and unload displays/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 display 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 the 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 a 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 objects to be searched by name. The object explorer contains two panels: the top panel and the bottom panel. The top panel presents the display 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 the ability to change the currently active layer. The bottom object search panel allows objects to be searched by name. In addition to this, the object type filter allows objects to be filtered by type as well. The object type filter also provides statistics regarding how many objects of a particular object type 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 is highlighted on the display designer and the Sammi pan command is used to pan the object to the top-left corner of the display designer surface. When working with large displays containing many small objects, it is sometimes difficult to figure out where the selected object is. In this situation, one can zoom into the display 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 means 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 display attributes and receive callbacks when a DDO's runtime data buffer is updated. By using this information, one can automate various test scenarios for a given format. The examples section below provides illustrations of how to automate sammi display testing.
  • Creating Objects Programatically

    This scripting feature can allow components in Sammi displays to be created programatically. The example below illustrates how shapes can progrmatically be added to a display in Sammi Studio. This allows import utilities to be created for various types of shape formats from other proprietary applications.
  • Format Debug Utility

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

Scripting Examples

  • Example 1

    Overview:         This example illustrates how scripting can be used at Runtime to process commands and gain access to display properties for currently active displays 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 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:
-------------Output from Example 1----------------------- Total active formats: 3 ************ 1 ************* Name: ndbm Title: Directory Path: /home/tester/sammi7/data_demo Zoom Value: 100 ************ 2 ************* Name: about-win Title: Directory Path: /home/tester/sammi7/user Zoom Value: 100 ************ 3 ************* Name: cmnd-win Title: Directory Path: /home/tester/sammi7/data Zoom Value: 100 ---------------------------------------------------------

Example 2:

Overview:       This example illustrates how the sammi object model can be utilized at Runtime to get component information for a specific display. 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
# # This example illustrates how the som and rte modules can be utilized to get component # level statistics for a given format. In the process, the example shows how to navigate # the format instance and the sammi object model to get access to the individual object # in the format. #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:
-------------Output from Example 2----------------------- Components Count by Type:Image = 1 VectorText = 16 Button = 1 Rectangle = 1 TextBox = 5 ---------------------------------------------------------

Example 3:

Overview:       This example shows how layer information for a particular display can be accessed via scripting. The example uses the region_demo3 display. 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
# # This example illustrates how to access layer information for a particular format using the # the sammi object model. # import rte# 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:
-------------Output from Example 3----------------------- 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, and data access information can be accessed using the sammi object model for a particular display. 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
# # This example illustrates how to query ddo properties for a given format using the sammi # object model. # 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# 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:
-------------Output from Example 4----------------------- Type = Integer, Name = short0 Location = ( 10, 70), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record1 short0', WriteKey = '' ********************************************************************************************** Type = Integer, Name = short3 Location = ( 90, 70), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record1 0', WriteKey = '' ********************************************************************************************** Type = Integer, Name = long0 Location = ( 210, 70), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record1 long0', WriteKey = '' ********************************************************************************************** Type = Integer, Name = long3 Location = ( 290, 70), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record1 4', WriteKey = '' ********************************************************************************************** Type = Integer, Name = short1 Location = ( 10, 90), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record2 short0', WriteKey = '' ********************************************************************************************** Type = Integer, Name = short4 Location = ( 90, 90), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record2 0', WriteKey = '' ********************************************************************************************** Type = Integer, Name = long1 Location = ( 210, 90), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record2 long0', WriteKey = '' ********************************************************************************************** Type = Integer, Name = long4 Location = ( 290, 90), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record2 4', WriteKey = '' ********************************************************************************************** Type = Integer, Name = short2 Location = ( 10, 110), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record3 short0', WriteKey = '' ********************************************************************************************** Type = Integer, Name = short5 Location = ( 90, 110), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record3 0', WriteKey = '' ********************************************************************************************** Type = Integer, Name = long2 Location = ( 210, 110), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record3 long0', WriteKey = '' ********************************************************************************************** Type = Integer, Name = long5 Location = ( 290, 110), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record3 4', WriteKey = '' ********************************************************************************************** Type = Real, Name = float0 Location = ( 10, 170), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record1 float0', WriteKey = '' ********************************************************************************************** Type = Real, Name = float3 Location = ( 90, 170), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record1 8', WriteKey = '' ********************************************************************************************** Type = Real, Name = double0 Location = ( 210, 170), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record1 double0', WriteKey = '' ********************************************************************************************** Type = Real, Name = double3 Location = ( 290, 170), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record1 12', WriteKey = '' ********************************************************************************************** Type = Real, Name = float1 Location = ( 10, 190), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record2 float0', WriteKey = '' ********************************************************************************************** Type = Real, Name = float4 Location = ( 90, 190), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record2 8', WriteKey = '' ********************************************************************************************** Type = Real, Name = double1 Location = ( 210, 190), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record2 double0', WriteKey = '' ********************************************************************************************** Type = Real, Name = double4 Location = ( 290, 190), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record2 12', WriteKey = '' ********************************************************************************************** Type = Real, Name = float0 Location = ( 10, 210), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record3 float0', WriteKey = '' ********************************************************************************************** Type = Real, Name = float5 Location = ( 90, 210), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record3 8', WriteKey = '' ********************************************************************************************** Type = Real, Name = double2 Location = ( 210, 210), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record3 double0', WriteKey = '' ********************************************************************************************** Type = Real, Name = double5 Location = ( 290, 210), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record3 12', WriteKey = '' ********************************************************************************************** Type = TextBox, Name = fixstr0 Location = ( 10, 290), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record1 fixstr0', WriteKey = '' ********************************************************************************************** Type = TextBox, Name = fixstr3 Location = ( 90, 290), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record1 20', WriteKey = '' ********************************************************************************************** Type = TextBox, Name = fixstr1 Location = ( 10, 310), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record2 fixstr0', WriteKey = '' ********************************************************************************************** Type = TextBox, Name = fixstr4 Location = ( 90, 310), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record2 20', WriteKey = '' ********************************************************************************************** Type = TextBox, Name = fixstr2 Location = ( 10, 330), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record3 fixstr0', WriteKey = '' ********************************************************************************************** Type = TextBox, Name = fixstr5 Location = ( 90, 330), Size = ( 72, 16) Data Access Type: Universal, LogicalServer = s2_ndbmsvr, ReadKey = 'ndbmtest1 record3 20', WriteKey = '' ********************************************************************************************** Type = Button, Name = Location = ( 222, 291), Size = ( 126, 55) Data Access Type: None ********************************************************************************************** ---------------------------------------------------------

Example 5:

Overview:       This example illustrates how shape information can be obtained from a particular displau. The example uses the 'fast_dobj' format to periodically update 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
# # This example illustrates how to query shape properties for a given format using the sammi # object model. #import rte import somtimer_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:
-------------Output from Example 5----------------------- --------------------------------------------------------- Shape Type | Location | Size | Color ---------------------------------------------------------- Rectangle | ( 71, 83) | ( 50, 50) | lightseagreen Ellipse | ( 96, 22) | ( 44, 45) | cadetblue4 Polygon | ( 43, -3) | ( 55, 52) | firebrick ********************************************************************************************** Shape Type | Location | Size | Color ---------------------------------------------------------- Rectangle | ( 90, 117) | ( 50, 50) | lightseagreen Ellipse | ( 29, 21) | ( 44, 45) | seagreen Polygon | ( -26, 117) | ( 55, 52) | magenta ********************************************************************************************** Shape Type | Location | Size | Color ---------------------------------------------------------- Rectangle | ( -1, -2) | ( 50, 50) | mediumvioletred Ellipse | ( -20, 83) | ( 44, 45) | dodgerblue Polygon | ( 71, 44) | ( 55, 52) | darkorchid **********************************************************************************************
>p> Example 6: Overview:       This example illustrates how Sammi scripting can be used to perform test automation for Sammi displays. 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
# # This example illustrates how scripting can be used to perform test automation in sammi runtime. # The example uses ndbm format as an example to illustrate how a particular format can be tested. # import rte import random import math import datetime# 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:
-------------Output from Example 6----------------------- Updated ddo 'long0' with data value 229 Updated ddo 'short0' with data value 179 Updated ddo 'float0' with data value 817 Updated ddo 'double0' with data value 759 The ddo 'short3' was correctly updated with data value 179 as expected. The ddo 'long3' was correctly updated with data value 229 as expected. The ddo 'float3' was correctly updated with data value 817 as expected. The ddo 'double3' was correctly updated with data value 759 as expected. ---------------------------------------------------------

Example 7:

Overview:       This example illustrates how the interface for the dobj ddo can be used to access it's 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
# # This example illustrates how to access the objects controlled by the dobj object. # The example adds the 'trans5_40' format to the runtime. A print message is generated # each time the specific dobj object is updated. The print message contains information about # the dobj object and the object that it controls. 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# 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:
dobj (name = , id = 572, location = (399,329)) was updated: display obj: type = Polyline , id = 288 , forecolor = red dobj (name = , id = 518, location = (669,329)) was updated: display obj: type = Polyline , id = 53 , forecolor = black dobj (name = , id = 535, location = (876,357)) was updated: display obj: type = Polygon , id = 369 , forecolor = magenta display obj: type = Text , id = 492 , forecolor = magenta dobj (name = , id = 525, location = (747,377)) was updated: display obj: type = Polygon , id = 145 , forecolor = magenta dobj (name = , id = 536, location = (877,405)) was updated: display obj: type = Polygon , id = 370 , forecolor = magenta display obj: type = Text , id = 493 , forecolor = magenta dobj (name = , id = 517, location = (469,399)) was updated: display obj: type = Polyline , id = 249 , forecolor = black display obj: type = Polyline , id = 260 , forecolor = black dobj (name = , id = 567, location = (138,348)) was updated: display obj: type = Polyline , id = 303 , forecolor = yellow dobj (name = , id = 568, location = (79,240)) was updated: display obj: type = Polyline , id = 348 , forecolor = black dobj (name = , id = 526, location = (749,439)) was updated: display obj: type = Polygon , id = 144 , forecolor = black dobj (name = , id = 538, location = (237,435)) was updated: display obj: type = Arc , id = 5 , forecolor = yellow display obj: type = Polyline , id = 15 , forecolor = yellow display obj: type = Text , id = 402 , forecolor = yellow dobj (name = , id = 573, location = (437,427)) was updated: display obj: type = Polyline , id = 282 , forecolor = yellow dobj (name = , id = 544, location = (168,447)) was updated: display obj: type = Polygon , id = 347 , forecolor = red display obj: type = Text , id = 478 , forecolor = red

Example 9:

Overview:       This example illustrates how the interface for the bitmap symbol DDO can be used to access it's 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
# # This example illustrates how to access properties for the bitmap symbol ddo. # The example adds the 'symbol_demo3' format to the runtime. A print message is generated # each time the specific bitmap symbol ddo is updated. The print message contains information about # the table name and symbol name associated with the ddo. 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#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:
bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_ne: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: bitmap symbol: table name = dfd-symbol, symbol name = sw_round_n: ...

Example 10:

Overview:       This example illustrates how the interface for the object icon DDO can be used to access it's 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
# # This example illustrates how to access properties for the object icon ddo. # The example adds the 'objicon_demo3' format to the runtime. A print message is generated # each time the specific object icon ddo is updated. The print message contains information about # the table name and symbol name associated with the ddo. 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#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:
object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valtran1: object icon: table name = valvelusym , symbol name = valopn: object icon: table name = valvelusym , symbol name = valopn: object icon: table name = valvelusym , symbol name = valopn: object icon: table name = valvelusym , symbol name = valopn: object icon: table name = valvelusym , symbol name = valopn: object icon: table name = valvelusym , symbol name = valopn: object icon: table name = valvelusym , symbol name = valopn: object icon: table name = valvelusym , symbol name = valopn: ...

Example 11:

Overview:       This example illustrates how the interface for the text symbol DDO can be used to access its 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
# # This example illustrates how to access properties for the text symbol ddo. # The example adds the 'texttable_demo3' format to the runtime. A print message is generated # each time the specific text symbol ddo is updated. The print message contains information about # the table name and symbol name associated with the ddo. 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#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:
text symbol: table name = sampleafs , symbol name = Fisher! text symbol: table name = sampleafs , symbol name = Fisher! text symbol: table name = sampleafs , symbol name = VAIL text symbol: table name = sampleafs , symbol name = head text symbol: table name = sampleafs , symbol name = COPPER MTN text symbol: table name = sampleafs , symbol name = taos text symbol: table name = sampleafs , symbol name = Salomon text symbol: table name = sampleafs , symbol name = head text symbol: table name = sampleafs , symbol name = VAIL text symbol: table name = sampleafs , symbol name = Salomon text symbol: table name = sampleafs , symbol name = Big Sky text symbol: table name = sampleafs , symbol name = Aspen text symbol: table name = sampleafs , symbol name = Salomon text symbol: table name = sampleafs , symbol name = Keystone text symbol: table name = sampleafs , symbol name = Aspen text symbol: table name = sampleafs , symbol name = Big Sky text symbol: table name = sampleafs , symbol name = Big Sky text symbol: table name = sampleafs , symbol name = COPPER MTN text symbol: table name = sampleafs , symbol name = Fisher! text symbol: table name = sampleafs , symbol name = head ...

Example 12:

Overview:       This example illustrates how shape animation can be performed using scripting in Sammi. The example adds the 'trans3_40' display 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
# # This example illustrates how the sammi object model and timer can be used to # perform shape animation at runtime. # import rte import som import random# 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
>p>

Creating Shapes using Script:

Overview:       This example illustrates how scripting can be used to programmatically create shapes in 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 proprietary applications. 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
# # This example shows how scripting can be used to progrmatically create shape objects in Studio. # import rte import fe import som#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:
-------------------------Create Shapes--------------------------- line pts = (10,150) (100,250) poly line pts = (10,280) (100,300) (150,350) (50,380) polygon pts = (150,50) (370,60) (250,100) (150,50) open spline pts = (200,150) (390,170) (300,230) (230,240) closed spline pts = (200,300) (390,320) (300,380) (230,390) (200,300) ellipse center = (470,100) ellipse radii (100,40) ellipse fore color = yellow arc center = (470,250) arc radii (80,60) arc angles = (0,130) img name = alarm img file type = 1 -----------------------------------------------------------------
Output  

SDI in Runtime

Overview:       This example illustrates how scripting and the qt based PySide library can be used for creating SDI (Single Document Interface) using sammi displays. The example adds a button panel at the top and an alarm panel at the bottom. The middle panel is used for displaying sammi displays that are shown based on button selection 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

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 display at runtime. The example uses the PySide library for creating an MDI interface and the exposed Sammi interfaces to collect display 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

Roadmap

The following features are currently under consideration for enhancing Sammi using python scripting.

·        Update Sammi Object Model

Currently the SOM module exposes interfaces for accessing attributes for Displays, Layers, Shapes and DDOs. The attributes for shapes and layers are fully exposed but the DDO only exposes common attributes. The specific attributes for each DDO needs to be exposed for the sammi object model to be complete. Furthermore, exposing various events specific to the ddo will make the object model more versatile for enhancing Sammi Runtime functionalities.

·        Utility Scripts

The idea is to allow the SOM module to be accessible from a stand alone python script and provide methods for reading and writing to a display(*.fmt) file. In addition to this, updating the sammi object model to allow format, layers, shape and DDO object creation. These features would allow the ability to programmatically create new complete displays. It would also allow post verification or modification of existing displays outside of Sammi.

·        Format Level Scripting

The idea is to provide a way to associate a python script with a specific display. A specific method within the script would get called on the add-window and delete-window event associated with the format. The sammi object model can then be utilized to update shapes and display on specific events.

·        Custom DDO

Just as a python scripting can be associated with a specific display, it would also be possible to associate it with a custom DDO instance. The idea is that the python script associated with the custom DDO would receive DDO specific Runtime events and would be responsible for performing drawing or updating of widgets. This would provide a way for a user to create a custom DDO and incorporate it in a Sammi display.

·        Alternative to Sammi API

The peer application written with the current Sammi api provides a very direct and straight forward interface between the Runtime and the peer application. However as a result of this architecture, the api has limited access to the sammi object model. By exposing the runtime events within the python script, it would be possible to achieve all the functionalities that the sammi api currently provides within the python script. Furthermore, full access to the sammi object model would allow additional means by which to manipulate format objects.

Leave a Reply

Your email address will not be published. Required fields are marked *