def __init__(self, gapps, simulation_id, Rids):
     self.gapps = gapps
     self.simulation_id = simulation_id
     self.Rids = Rids
     self.rid_idx = 0
     self.keepLoopingFlag = True
     self.publish_to_topic = simulation_input_topic(simulation_id)
Exemplo n.º 2
0
    def __init__(self, simulation_id, gridappsd_obj, ACline, obj_msr_loadsw):
        """ Create a ``CapacitorToggler`` object

        This object should be used as a subscription callback from a ``GridAPPSD``
        object.  This class will toggle the capacitors passed to the constructor
        off and on every five messages that are received on the ``fncs_output_topic``.

        Note
        ----
        This class does not subscribe only publishes.

        Parameters
        ----------
        simulation_id: str
            The simulation_id to use for publishing to a topic.
        gridappsd_obj: GridAPPSD
            An instatiated object that is connected to the gridappsd message bus
            usually this should be the same object which subscribes, but that
            isn't required.
        """
        self._gapps = gridappsd_obj
        self._simulation_id = simulation_id
        self._ACline = ACline
        self._obj_msr_loadsw = obj_msr_loadsw
        self._message_count = 0
        self._last_toggle_on = False
        self._open_diff = DifferenceBuilder(simulation_id)
        self._close_diff = DifferenceBuilder(simulation_id)
        self._publish_to_topic = simulation_input_topic(simulation_id)
        self._flag = 0
        self._start_time = 0
        _log.info("Building cappacitor list")
Exemplo n.º 3
0
def test_listener_multi_topic(gridappsd_client):
    gappsd = gridappsd_client

    class Listener:
        def __init__(self):
            self.call_count = 0

        def reset(self):
            self.call_count = 0

        def on_message(self, headers, message):
            print("Message was: {}".format(message))
            self.call_count += 1

    listener = Listener()

    input_topic = t.simulation_input_topic("5144")
    output_topic = t.simulation_output_topic("5144")

    gappsd.subscribe(input_topic, listener)
    gappsd.subscribe(output_topic, listener)

    gappsd.send(input_topic, "Any message")
    sleep(1)
    assert 1 == listener.call_count
    listener.reset()
    gappsd.send(output_topic, "No big deal")
    sleep(1)
    assert 1 == listener.call_count
Exemplo n.º 4
0
def send_command(msg):
    goss = GOSS()
    goss.connect()
    # print(json.dumps(msg,indent=2))
    request = json.dumps(msg)
    status = goss.send(simulation_input_topic(simulation_id), request)
    print(status)
Exemplo n.º 5
0
def test_alarm_output(sim_config_file, sim_result_file):

    simulation_id = None
    sim_config_file = os.path.join(
        os.path.dirname(__file__),
        f"simulation_config_files/{sim_config_file}")
    sim_result_file = os.path.join(
        os.path.dirname(__file__),
        f"simulation_baseline_files/{sim_result_file}")

    assert os.path.exists(
        sim_config_file
    ), f"File {sim_config_file} must exist to run simulation test"

    with startup_containers():
        with gappsd() as gapps:
            os.makedirs("/tmp/output", exist_ok=True)
            with open("/tmp/output/simulation.output", 'w') as outfile:
                sim_complete = False
                rcvd_measurement = False

                def onmeasurement(sim, timestep, measurements):
                    nonlocal rcvd_measurement
                    # if not rcvd_measurement:
                    rcvd_measurement = True
                    LOGGER.info('A measurement happened at %s', timestep)

                def onfinishsimulation(sim):
                    nonlocal sim_complete
                    sim_complete = True
                    print("Completed simulator")

                with open(sim_config_file) as fp:
                    run_config = json.load(fp)
                    print(run_config["simulation_config"]["start_time"])

                sim = Simulation(gapps, run_config)

                LOGGER.info('Starting the  simulation')
                sim.add_onmesurement_callback(onmeasurement)
                sim.add_oncomplete_callback(onfinishsimulation)
                LOGGER.info('sim.add_onmesurement_callback')
                LOGGER.info("Querying Alarm topic for alarms")
                sim.start_simulation()
                print(sim.simulation_id)
                alarms_topic = t.service_output_topic('gridappsd-alarms',
                                                      sim.simulation_id)
                log_topic = t.simulation_output_topic(sim.simulation_id)
                input_topic = t.simulation_input_topic(sim.simulation_id)
                gapps.subscribe(alarms_topic, on_message)
                gapps.subscribe(log_topic, on_message)
                # gapps.subscribe(input_topic, on_message)

                while not sim_complete:
                    LOGGER.info('Sleeping')
                    sleep(30)
Exemplo n.º 6
0
    def __init__(self, simulation_id, gridappsd_obj, reg_list, cap_list,
                 demand, line, xfmr, msr_mrids_demand, msr_mrids_cap,
                 msr_mrids_reg, obj_msr_loadsw, switches, obj_msr_inv,
                 obj_msr_node):
        """ Create a ``CapacitorToggler`` object

        This object should be used as a subscription callback from a ``GridAPPSD``
        object.  This class will toggle the capacitors passed to the constructor
        off and on every five messages that are received on the ``fncs_output_topic``.

        Note
        ----
        This class does not subscribe only publishes.

        Parameters
        ----------
        simulation_id: str
            The simulation_id to use for publishing to a topic.
        gridappsd_obj: GridAPPSD
            An instatiated object that is connected to the gridappsd message bus
            usually this should be the same object which subscribes, but that
            isn't required.
        capacitor_list: list(str)
            A list of capacitors mrids to turn on/off
        """
        self._gapps = gridappsd_obj
        self._flag = 0
        self.reg_list = reg_list
        self._cap_list = cap_list
        self._store = []
        self._message_count = 0
        self._last_toggle_on = False
        self._cap_open_diff = DifferenceBuilder(simulation_id)
        self._cap_close_diff = DifferenceBuilder(simulation_id)
        self._tap_open_diff = DifferenceBuilder(simulation_id)
        self._tap_close_diff = DifferenceBuilder(simulation_id)
        self._publish_to_topic = simulation_input_topic(simulation_id)
        self._pv_qpower = DifferenceBuilder(simulation_id)
        self.msr_mrids_loadsw = obj_msr_loadsw
        self.msr_mrids_demand = msr_mrids_demand
        self.msr_mrids_cap = msr_mrids_cap
        self.msr_mrids_reg = msr_mrids_reg
        self.LineData = line
        self.DemandData = demand
        self.xfmr = xfmr
        self.obj_msr_inv = obj_msr_inv
        self.obj_msr_node = obj_msr_node
        # self.Inverter_PnS = Inverter_PnS
        # self.obj_msr_sync = obj_msr_sync
        self.TOP = []
        self.switches = switches
        self.flag = 0
        _log.info("Building cappacitor list")
Exemplo n.º 7
0
    def __init__(self, simulation_id, gridappsd_obj, ACline, obj_msr_loadsw,
                 obj_msr_reg, switches, regulators):
        """ Create a ``CapacitorToggler`` object

		This object should be used as a subscription callback from a ``GridAPPSD``
		object.  This class will toggle the capacitors passed to the constructor
		off and on every five messages that are received on the ``fncs_output_topic``.

		The five message mentioned above refers to DEFAULT_MESSAGE_PERIOD

		Note
		----
		This class does not subscribe only publishes.

		Parameters
		----------
		simulation_id: str
		    The simulation_id to use for publishing to a topic.
		gridappsd_obj: GridAPPSD
		    An instatiated object that is connected to the gridappsd message bus
		    usually this should be the same object which subscribes, but that
		    isn't required.
		capacitor_list: list(str)
		    A list of capacitors mrids to turn on/off
		"""
        self._gapps = gridappsd_obj

        # the five variables below are different than the ones presented on original file
        # have been created by Shiva to see AC lines and switch
        self._simulation_id = simulation_id
        self._ACline = ACline
        self._obj_msr_loadsw = obj_msr_loadsw
        self._obj_msr_reg = obj_msr_reg
        self._flag = 0
        self._start_time = 0
        self.check = True
        self.inp = False
        self._switches = switches
        self._regulators = regulators

        self._message_count = 0
        self._last_toggle_on = False
        self._open_diff = DifferenceBuilder(simulation_id)
        self._close_diff = DifferenceBuilder(simulation_id)
        self._tap_close_diff = DifferenceBuilder(simulation_id)

        self._publish_to_topic = simulation_input_topic(simulation_id)
        _log.info("Building capacitor list")
def _main():
    global sim_id, gapps

    if len(sys.argv) < 3 or '-help' in sys.argv:
        usestr = '\nUsage: ' + sys.argv[
            0] + ' simulation_id tap|reg|cap|switch\n'
        usestr += '''
Optional command line arguments:
        -help: show this usage message
        '''
        print(usestr, file=sys.stderr, flush=True)
        exit()

    gapps = GridAPPSD()

    sim_id = sys.argv[1]

    diff = DifferenceBuilder(sim_id)

    # hardwired for 13assets
    if sys.argv[2] == 'tap' or sys.argv[2] == 'reg':
        reg_id = '_A480E0A9-AD2B-4D8E-9478-71C29F738221'  # node RG60.2
        diff.add_difference(reg_id, 'TapChanger.step', 5, 8)
    elif sys.argv[2] == 'cap':
        cap_id = '_28456F60-7196-47E4-9BE6-54F7EAABC04A'  # bus 611
        diff.add_difference(cap_id, 'ShuntCompensator.sections', 0, 1)
    else:
        switch_id = '_4E1B3F09-CB88-4A5E-8198-24490EE7FC58'  # between bus 671-692
        diff.add_difference(switch_id, 'Switch.open', 1, 0)

    msg = diff.get_message()
    print(json.dumps(msg))

    publish_to_topic = simulation_input_topic(sim_id)

    gapps.send(publish_to_topic, json.dumps(msg))

    time.sleep(2)

    gapps.disconnect()
Exemplo n.º 9
0
def callback(headers, message):
    global end_program, flag, w, log_timestamps
    log_timestamp = []
    publish_to_topic = simulation_input_topic(simulation_id)
    if type(message) == str:
        message = json.loads(message)
    if 'message' not in message:
        if message['processStatus'] == 'COMPLETE' or \
           message['processStatus']=='CLOSED':
            print('The End')
            end_program = True
    else:
        #Uncomment for troubleshooting
        print(message)
        '''
        Only runs the first output query. Grabs the keys from the message, looks them up for their real names, and
        writes the header with the real names while still using the mrids as headers for dictwriter purposes.
        '''
        if flag == 0:
            header_mrids = message['message']['measurements'].keys()
            header_names = []
            print(header_mrids)
            for i in header_mrids:
                lookup_mrid = next(item for item in meas_object_list
                                   if item['measid'] == i)
                lookup_name = lookup_mrid['name']
                header_names.append(lookup_name)
            w = csv.DictWriter(f, header_mrids)
            print(header_names)
            header_names_dict = dict(zip(list(header_mrids), header_names))
            w.writerow(header_names_dict)
            flag = 1
        else:
            pass

        print(type(message))
        w.writerow(message['message']['measurements'])
        log_timestamps.append(SIMULATION_TIME)
Exemplo n.º 10
0
    def __init__(self, simulation_id, gridappsd_obj, capacitor_list):
        """ Create a ``CapacitorToggler`` object

        This object should be used as a subscription callback from a ``GridAPPSD``
        object.  This class will toggle the capacitors passed to the constructor
        off and on every five messages that are received on the ``fncs_output_topic``.

        Note
        ----
        This class does not subscribe only publishes.

        Parameters
        ----------
        simulation_id: str
            The simulation_id to use for publishing to a topic.
        gridappsd_obj: GridAPPSD
            An instatiated object that is connected to the gridappsd message bus
            usually this should be the same object which subscribes, but that
            isn't required.
        capacitor_list: list(str)
            A list of capacitors mrids to turn on/off
        """
        self._gapps = gridappsd_obj
        self._cap_list = capacitor_list
        self._message_count = 0
        self._last_toggle_on = False
        self._open_diff = DifferenceBuilder(simulation_id)
        self._close_diff = DifferenceBuilder(simulation_id)
        self._publish_to_topic = simulation_input_topic(simulation_id)
        _log.info("Building cappacitor list")
        for cap_mrid in capacitor_list:
            _log.debug(f"Adding cap sum difference to list: {cap_mrid}")
            self._open_diff.add_difference(cap_mrid,
                                           "ShuntCompensator.sections", 0, 1)
            self._close_diff.add_difference(cap_mrid,
                                            "ShuntCompensator.sections", 1, 0)
Exemplo n.º 11
0
    def __init__(self, simulation_id, gridappsd_obj, model_mrid, start_time, app_config={}):
        """ Create a ``Solar_Forecast`` object


        Note
        ----
        This class does not subscribe only publishes.

        Parameters
        ----------
        simulation_id: str
            The simulation_id to use for publishing to a topic.
        gridappsd_obj: GridAPPSD
            An instatiated object that is connected to the gridappsd message bus
            usually this should be the same object which subscribes, but that
            isn't required.

        """
        _log.info("Init application")
        self.simulation_id = simulation_id
        self._gapps = gridappsd_obj
        self.fidselect = model_mrid
        self._publish_to_topic = simulation_input_topic(simulation_id)
        self._start_time = start_time
        self._end_time = start_time + 3600 * 24
        self._message_count = 0
        self._run_freq = app_config.get('run_freq', 30)
        self._run_realtime = app_config.get('run_realtime', True)
        self._port = '9002'
        print(self._port )
        self._weather_df = None
        # self._weather_df = query_weather.query_weather(self._start_time,self._end_time)

        self.resFolder = ""

        MainDir=""
        circuit_name = ""
        self.resFolder = os.path.join(MainDir, 'adms_result_' + circuit_name + '_' + str(self._start_time))
        self._result_csv = ResultCSV()
        self._result_csv.create_result_folder(self.resFolder)
        self._result_csv.create_result_file(self.resFolder, 'result.csv', 'second,epoch time,GHI,forecast time,Forecast GHI')

        # self.create_result_file(self.resFolder)
        # self._results, self._res_csvfile, self._results_writer = self.create_result_file(self.resFolder, 'second,epoch time,GHI,forecast time,Forecast GHI')

        ctx = zmq.Context()
        self._skt = ctx.socket(zmq.PUB)
        if running_on_host():
            self._skt.bind('tcp://127.0.0.1:{}'.format(self._port))
        else:
            self._skt.bind('tcp://*:{}'.format(self._port))

        time.sleep(.3)
        signal.signal(signal.SIGTERM, self.signal_handler)
        signal.signal(signal.SIGINT, self.signal_handler)

        obj = dict(first=dict(first=1, time=1))
        jobj = json.dumps(obj).encode('utf8')
        zobj = zlib.compress(jobj)
        print('zipped pickle is %i bytes' % len(zobj))
        self._skt.send(zobj)
Exemplo n.º 12
0
    def send_command(self, object_ids, attributes, forward_values,
                     reverse_values, sim_id=None):
        """Function for sending a command into a running simulation.
        This is partly a wrapper to DifferenceBuilder, but also sends
        the command into the simulation.

        Note all list parameters below must be 1:1. In other words,
        object_ids[3] should correspond to attributes[3], etc.

        :param object_ids: List of mrids of objects to command.
        :param attributes: List of CIM attributes belonging to the
            objects. These attributes are what we're actually
            commanding/changing.
        :param forward_values: List of new values for attributes.
        :param reverse_values: List of old (current) values for
            attributes.
        :param sim_id: Simulation ID. If None, will attempt to use
            self.sim.simulation_id. If that is also None, ValueError
            will be raised.

        :returns: Dictionary representing the message that gets sent in.
            If no message will be sent (if input lists are empty),
            returns None instead.
        """
        # Ensure we get lists.
        if ((not isinstance(object_ids, list))
                or (not isinstance(attributes, list))
                or (not isinstance(forward_values, list))
                or (not isinstance(reverse_values, list))):
            m = 'object_ids, attributes, forward_values, and reverse_values '\
                'must all be lists!'
            raise TypeError(m)

        # Ensure lists are the same length.
        if not (len(object_ids)
                == len(attributes)
                == len(forward_values)
                == len(reverse_values)):
            m = 'object_ids, attributes, forward_values, and reverse_values '\
                'must be the same length!'
            raise ValueError(m)

        # Don't bother continuing if the lists are empty.
        if len(object_ids) == 0:
            self.log.info('send_command given empty lists, returning None.')
            return None

        # Ensure we have a simulation ID.
        if sim_id is None:
            try:
                sim_id = self.sim.simulation_id
            except AttributeError:
                m = ('sim_id input is None, and so is self.sim.simulation_id. '
                     'In order to send a command, we must have a sim_id.')
                raise ValueError(m) from None

        self.log.debug('Input checks complete for send_command.')

        # Initialize difference builder.
        diff_builder = DiffBuilder(simulation_id=sim_id)
        self.log.debug('DifferenceBuilder initialized.')

        # Iterate to build add differences.
        for k in range(len(object_ids)):
            diff_builder.add_difference(object_id=object_ids[k],
                                        attribute=attributes[k],
                                        forward_value=forward_values[k],
                                        reverse_value=reverse_values[k])

        # Get the message and log it.
        msg = diff_builder.get_message()
        msg_str = json.dumps(msg)
        self.log.info('Preparing to send following command: {}'
                      .format(msg_str))

        # Send command to simulation.
        self.gad.send(topic=topics.simulation_input_topic(sim_id),
                      message=msg_str)

        # Return the message in case we want to examine it, audit, etc.
        # Mainly useful for testing at this point.
        return msg
Exemplo n.º 13
0
def _main():
    parser = argparse.ArgumentParser()
    parser.add_argument("simulation_id",
                        help="Simulation id to use for responses on the message bus.")
    parser.add_argument("request",
                        help="Simulation Request")
    # These are now set through the docker container interface via env variables or defaulted to
    # proper values.
    #
    # parser.add_argument("-u", "--user", default="system",
    #                     help="The username to authenticate with the message bus.")
    # parser.add_argument("-p", "--password", default="manager",
    #                     help="The password to authenticate with the message bus.")
    # parser.add_argument("-a", "--address", default="127.0.0.1",
    #                     help="tcp address of the mesage bus.")
    # parser.add_argument("--port", default=61613, type=int,
    #                     help="the stomp port on the message bus.")
    #
    opts = parser.parse_args()
    sim_output_topic = simulation_output_topic(opts.simulation_id)
    sim_input_topic = simulation_input_topic(opts.simulation_id)
    sim_request = json.loads(opts.request.replace("\'",""))
    model_mrid = sim_request["power_system_config"]["Line_name"]
    gapps = GridAPPSD(opts.simulation_id, address=utils.get_gridappsd_address(),
                      username=utils.get_gridappsd_user(), password=utils.get_gridappsd_pass())
    capacitors_dict = {}
    switches_dict = {}
    capacitors_meas_dict = {}
    switches_meas_dict = {}

    request = {
        "modelId": model_mrid,
        "requestType": "QUERY_OBJECT_DICT",
        "resultFormat": "JSON",
        "objectType": "LinearShuntCompensator"
        }

    response = gapps.get_response("goss.gridappsd.process.request.data.powergridmodel",request)
    for capacitor in response["data"]:
        capacitors_dict[capacitor["id"]] = capacitor

    request = {
        "modelId": model_mrid,
        "requestType": "QUERY_OBJECT_DICT",
        "resultFormat": "JSON",
        "objectType": "LoadBreakSwitch"
        }

    response = gapps.get_response("goss.gridappsd.process.request.data.powergridmodel",request)
    for switch in response["data"]:
        switches_dict[switch["id"]] = switch

    #print(capacitors_dict)
    #print(switches_dict)
    
    request = {"modelId": model_mrid,
               "requestType": "QUERY_OBJECT_MEASUREMENTS",
               "resultFormat": "JSON",
               "objectType": "LinearShuntCompensator"
               }
    
    response = gapps.get_response("goss.gridappsd.process.request.data.powergridmodel",request)
    for measurement in response["data"]:
        capacitors_meas_dict[measurement["measid"]] = measurement
        
    request = {"modelId": model_mrid,
               "requestType": "QUERY_OBJECT_MEASUREMENTS",
               "resultFormat": "JSON",
               "objectType": "LoadBreakSwitch"
               }
    
    response = gapps.get_response("goss.gridappsd.process.request.data.powergridmodel",request)
    for measurement in response["data"]:
        switches_meas_dict[measurement["measid"]] = measurement

    #print(capacitors_meas_dict)
    #print(switches_meas_dict)

    #capacitors_dict = get_capacitor_measurements(gapps, model_mrid)
    #switches_dict = get_switch_measurements(gapps, model_mrid)
    subscriber = SimulationSubscriber(opts.simulation_id, gapps, capacitors_dict, switches_dict, capacitors_meas_dict, switches_meas_dict)
    gapps.subscribe(sim_input_topic, subscriber)
    gapps.subscribe(sim_output_topic, subscriber)
    while True:
        time.sleep(0.1)