Testing Python Event Manager Scripts

When you create Python scripts for Event Manager, you can test the scripts from the Proficy Code Editor.

The Event Manager creates an object from your EventHandlerState class the first time an event-action attempts to run your script. Thereafter, it calls the do_event_action method to run the script. In your test code, you need to emulate these two steps.

Example:

If your script doesn’t depend on the event-action context or the event context, then you can actually write you test code as follows. Note the use of sys.stdout.flush() to flush the output. This is necessary so that the print output shows up in the MAC_EMRP.out file.

import cimplicity

class EventHandlerState:
    def __init__(self, event_action_context: cimplicity.EMEventActionContext):
        pass

    def do_shutdown(self, event_data: cimplicity.CimEMEvent):
        pass

    def do_event_action(self, event_data: cimplicity.CimEMEvent):
        cimplicity.log_status(
            cimplicity.StatusSeverity.SUCCESS, "myscript", "it ran")
        print("it ran")
        sys.stdout.flush()

def do_test():
    handler_state = EventHandlerState(None)
    handler_state.do_event_action(None)

if __name__ == "__main__":
    do_test()

To test the script run the command from the command palette (Ctrl+Shift+P) and then select Python: Run Python File in Terminal or you can click in the upper right of the window.

Advanced Script

In more advanced cases, you will want to pass a real event-action context and a real event context. Consult the CIMPLICITY Python API (cimplicity.html) for information about the properties for EMEventActionContext and CimEMEvent.

The following example represents testing a point event for a CIMPLICITY class object.
import cimplicity
import sys
import time

class EventHandlerState:

    def __init__(self, event_action_context: cimplicity.EMEventActionContext):
        # store the object attributes for later use
        self.obj_attrs = event_action_context.object_attributes
        print(f"__init__: obj_attrs: {self.obj_attrs}")
        sys.stdout.flush()

    def do_event_action(self, event_data: cimplicity.CimEMEvent):
        cimplicity.log_status(
            cimplicity.StatusSeverity.SUCCESS, "myscript", "running")
        print(f"event_id: {event_data.event_id}")
        print(f"action_id: {event_data.action_id}")
        print(f"object_id: {event_data.object_id}")
        print(f"timestamp_local: {event_data.timestamp_local}")
        print(f"event type: {event_data.type}")
        print(f"obj_attrs: {self.obj_attrs}")
        if event_data.point_event is not None:
            print("point event:")
            pe: cimplicity.CimEMPointEvent = event_data.point_event
            print(f"  point ID: {pe.id}")
            print(f"  state: {pe.state}")
            print(f"  quality: {pe.quality}")
            print(f"  timestamp_local: {pe.timestamp_local}")
        sys.stdout.flush()

    def do_shutdown(self, event_data: cimplicity.CimEMEvent):
        pass

def do_test():
    # construct an EventHandlerState object
    ea_ctx = cimplicity.EMEventActionContext(
        "WORKUNIT03.OfflineForMaintEvent", "WORKUNIT03.OfflineForMaintAction",
        "WORKUNIT03", {"A_HASSCANNER": "0", "A_HASBUFFER": "1"})
    eh_state = EventHandlerState(ea_ctx)
    # construct the CimEMEvent and CimEMPointEvent objects
    ts_cimp = time.time_ns() / 100
    quality = (cimplicity.QualityFlags.IS_AVAILABLE
               | cimplicity.QualityFlags.IS_IN_RANGE
               | cimplicity.QualityFlags.ALARMS_ENABLED
               | cimplicity.QualityFlags.ACK_OCCURRED)
    pt_event = cimplicity.CimEMPointEvent(
        "WORKUNIT03.OfflineForMaintPoint", "value", quality, ts_cimp,
        cimplicity.PointState.NORMAL, 0)
    # call the do_event_action method
    eh_state.do_event_action(cimplicity.CimEMEvent(
        cimplicity.EventType.POINT_CHANGE, ea_ctx.object_id,
        ea_ctx.event_id, ea_ctx.action_id, ts_cimp, None, pt_event,
        None))

if __name__ == "__main__":
    do_test()