def reg_msg(name, fv=1, rv=0): if name not in reg_name_map: print('No regulator named ' + name) return None _diff = DifferenceBuilder(simulation_id) _diff.add_difference(reg_name_map[name]['id'], "TapChanger.step", fv, rv) msg = _diff.get_message() return msg
def switch_msg(name, fv=1, rv=0): if name not in switch_name_map: print('No switch named ' + name) return None _diff = DifferenceBuilder(simulation_id) # _diff.add_difference(switch_name_map[name], "Switch.open", 1, 0) _diff.add_difference(switch_name_map[name], "Switch.open", fv, rv) msg = _diff.get_message() return msg
def pv_msg(name, fv_p=0, fv_q=0, rv_p=0, rv_q=0): if name not in pv_name_map: print('No pv named ' + name) return None # generators = query_model.get_generators(fid_select) # generator_name_map = {generator['name']: generator['id'] for generator in generators} # msg =create_message(generator_name_map[name], "SynchronousMachine.p", 0, 0) # msg2 = create_message(generator_name_map[name], "SynchronousMachine.q", 0, 0) # msg['message']['forward_differences'].append(msg2['message']['forward_differences'][0]) # msg['message']['forward_differences'].append(msg2['message']['forward_differences'][0]) _diff = DifferenceBuilder(simulation_id) _diff.add_difference(generator_name_map[name], "PowerElectronicsConnection.p", fv_p, rv_p) _diff.add_difference(generator_name_map[name], "PowerElectronicsConnection.q", fv_q, rv_q) msg = _diff.get_message() return msg
def on_message(self, header, message): # TODO workaround for broken unsubscribe method if not self.keepLoopingFlag: return msgdict = message['message'] ts = msgdict['timestamp'] print('simulation timestamp: ' + str(ts), flush=True) rid = self.Rids[self.rid_idx] reg_diff = DifferenceBuilder(self.simulation_id) reg_diff.add_difference(rid, 'TapChanger.step', 0, 1) msg = reg_diff.get_message() print(msg) self.gapps.send(self.publish_to_topic, json.dumps(msg)) reg_diff.clear() self.rid_idx += 1 if self.rid_idx == len(self.Rids): self.keepLoopingFlag = False
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()
class SwitchingActions(object): """ A simple class that handles publishing forward and reverse differences The object should be used as a callback from a GridAPPSD object so that the on_message function will get called each time a message from the simulator. During the execution of on_meessage the `CapacitorToggler` object will publish a message to the simulation_input_topic with the forward and reverse difference specified. """ 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") def on_message(self, headers, message): """ Handle incoming messages on the simulation_output_topic for the simulation_id Parameters ---------- headers: dict A dictionary of headers that could be used to determine topic of origin and other attributes. message: object A data structure following the protocol defined in the message structure of ``GridAPPSD``. Most message payloads will be serialized dictionaries, but that is not a requirement. """ if type(message) == str: message = json.loads(message) if 'gridappsd-alarms' in headers['destination']: message = json.loads(message.replace("\'", "")) for m in message: print(m['created_by']), m['equipment_name'] # print(s) else: if not message['message']['measurements']: return self._message_count += 1 flag_fault = 0 flag_event = 0 Top = Topology(self.msr_mrids_loadsw, self.switches, message, self.LineData) open_switch = Top.curr_top() # print(open_switch) d = PowerData(self.msr_mrids_demand, message, self.xfmr, self.obj_msr_inv, self.LineData, open_switch, self.obj_msr_node) platformload = d.demand() print('Platform Load is obtained....') with open('output.json', 'w') as json_file: json.dump(message, json_file) # print(messvar) if self._message_count % message_period == 0: no_opt = LEGACY_DEV(self.msr_mrids_cap, self.msr_mrids_reg, message) statusP_c = no_opt.cap_() statusP_r = no_opt.reg_() print('form platform capacitor switch status', statusP_c) print('from platform regulator tap position', statusP_r) # print('\n \n ........................') # print('Platform Status')DifferenceBuilder(simulation_id) # print('........................\n \n') ###calling VVO capreg_st = WSUVVO() statusO_c, statusO_r, flag = capreg_st.VVO9500( self.LineData, platformload, open_switch, self.xfmr) print('\n \n ........................') print('Optimization results') print('capacitor switch status', statusO_c) print('regulator tap position', statusO_r) print('........................\n \n') # for inv in self.obj_msr_inv: # for qpv in Qpvcontrol0: # if inv['bus'] == qpv['bus']: # # print(eqid) # # print(mrid) # qpv['mrid'] = inv['eqid'] # print(Qpvcontrol0) # for qpv_mrid in Qpvcontrol0 : # self._pv_qpower.add_difference(qpv_mrid['mrid'], "PowerElectronicsConnection.q", qpv_mrid['val'], 0) # msg = self._pv_qpower.get_message() # self._gapps.send(self._publish_to_topic, json.dumps(msg)) # print(msg) # total number of control variables are 12 # ch = [] # for m in range(10): # if statusO_c[m] == 0: # ch.append(self._cap_list[m]) if flag == 1: indx = 0 for cap_mrid in self._cap_list: if statusO_c[indx] == None: # self._close_diff.add_difference(cap_mrid, "ShuntCompensator.sections", statusP_c[indx], 1) # indx += 1 self._cap_close_diff.add_difference( cap_mrid, "ShuntCompensator.sections", statusP_c[indx], 0) indx += 1 else: # self._close_diff.add_difference(cap_mrid, "ShuntCompensator.sections", statusO_c[indx], 1) # indx += 1 self._cap_close_diff.add_difference( cap_mrid, "ShuntCompensator.sections", statusO_c[indx], 0) indx += 1 msg = self._cap_close_diff.get_message() self._gapps.send(self._publish_to_topic, json.dumps(msg)) ind = 0 for reg_mrid in self.reg_list: # self._close_diff.add_difference(reg_mrid, "TapChanger.step", statusO_r[ind], 0) self._tap_close_diff.add_difference( reg_mrid, "TapChanger.step", statusO_r[ind], 0) ind += 1 msg = self._tap_close_diff.get_message() self._gapps.send(self._publish_to_topic, json.dumps(msg))
class CapacitorToggler(object): """ A simple class that handles publishing forward and reverse differences The object should be used as a callback from a GridAPPSD object so that the on_message function will get called each time a message from the simulator. During the execution of on_meessage the `CapacitorToggler` object will publish a message to the simulation_input_topic with the forward and reverse difference specified. """ 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) def on_message(self, headers, message): """ Handle incoming messages on the simulation_output_topic for the simulation_id Parameters ---------- headers: dict A dictionary of headers that could be used to determine topic of origin and other attributes. message: object A data structure following the protocol defined in the message structure of ``GridAPPSD``. Most message payloads will be serialized dictionaries, but that is not a requirement. """ self._message_count += 1 _log.debug(f"new message count is: {self._message_count}") # Every message_period messages we are going to turn the capcitors on or off depending # on the current capacitor state. if self._message_count % message_period == 0: if self._last_toggle_on: _log.debug("count: {} toggling off".format( self._message_count)) msg = self._close_diff.get_message(epoch=message['timestamp']) self._last_toggle_on = False else: _log.debug("count: {} toggling on".format(self._message_count)) msg = self._open_diff.get_message(epoch=message['timestamp']) self._last_toggle_on = True self._gapps.send(self._publish_to_topic, json.dumps(msg))
class LearnPlatform(object): """ A simple class that handles publishing forward and reverse differences The object should be used as a callback from a GridAPPSD object so that the on_message function will get called each time a message from the simulator. During the execution of on_meessage the `CapacitorToggler` object will publish a message to the simulation_input_topic with the forward and reverse difference specified. """ 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") def on_message(self, headers, message): """ Handle incoming messages on the simulation_output_topic for the simulation_id Parameters ---------- headers: dict A dictionary of headers that could be used to determine topic of origin and other attributes. message: object A data structure following the protocol defined in the message structure of ``GridAPPSD``. Most message payloads will be serialized dictionaries, but that is not a requirement. """ if type(message) == str: message = json.loads(message) # Some demo for understanding object and measurement mrids. Print the status of several switches timestamp = message["message"]["timestamp"] meas_value = message['message']['measurements'] # Find interested mrids. We are only interested in Pos of the switches ds = [d for d in self._obj_msr_loadsw if d['type'] == 'Pos'] # Store the open switches Loadbreak = [] for d1 in ds: if d1['measid'] in meas_value: v = d1['measid'] p = meas_value[v] if p['value'] == 0: Loadbreak.append(d1['eqname']) print('.....................................................') print('The total number of open switches:', len(set(Loadbreak))) print(timestamp, set(Loadbreak)) self._flag += 1 # Open one of the switches if self._flag == 5: swmrid = '_BC63E102-37AD-4269-BB19-8351403B9B60' self._open_diff.add_difference(swmrid, "Switch.open", 1, 0) msg = self._open_diff.get_message() print(msg) self._gapps.send(self._publish_to_topic, json.dumps(msg)) swmrid = '_7262F9C3-2E8B-4069-AA13-BF4A655ACE35' self._open_diff.add_difference(swmrid, "Switch.open", 0, 1) msg = self._open_diff.get_message() print(msg) self._gapps.send(self._publish_to_topic, json.dumps(msg))
class NodalVoltage(object): """ A simple class that handles publishing forward and reverse differences Important in handling the gridappsd platform The object should be used as a callback from a GridAPPSD object so that the on_message function will get called each time a message from the simulator. During the execution of on_message the `CapacitorToggler` object will publish a message to the simulation_input_topic with the forward and reverse difference specified. """ 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``. 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._flag = 0 self._start_time = 0 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 capacitor list") def on_message(self, headers, message): # this section is modified by shiva """ Handle incoming messages on the simulation_output_topic for the simulation_id Parameters ---------- headers: dict A dictionary of headers that could be used to determine topic of origin and other attributes. message: object A data structure following the protocol defined in the message structure of ``GridAPPSD``. Most message payloads will be serialized dictionaries, but that is not a requirement. """ if type(message) == str: message = json.loads(message) # Some demo for understanding object and measurement mrids. # Print the status of several switches timestamp = message["message"]["timestamp"] meas_value = message['message']['measurements'] # SWITCHES # Find interested mrids. We are only interested in Pos of the switches ds = [d for d in self._obj_msr_loadsw if d['type'] == 'Pos'] print("\n ******* ds ********* \n ") print(ds) # Store the open switches Loadbreak = [] for d1 in ds: if d1['measid'] in meas_value: v = d1['measid'] p = meas_value[v] if p['value'] == 0: Loadbreak.append(d1['eqname']) print('.....................................................') print('The total number of open switches:', len(set(Loadbreak))) print(timestamp, set(Loadbreak)) # print(sh) # PNV # Find interested mrids. We are only interested in PNV phase_check = [d for d in self._ACline if d['phases'] == 'A'] print("\n ******* phase check ********* \n ") print(phase_check) # print(sh) # Store the open switches phaseA_PNV = [] for d1 in phase_check: if d1['measid'] in meas_value: v = d1['measid'] p = meas_value[v] # print ('\n p \n', p) # print(sh) if p['magnitude'] > 2000 and p['magnitude'] < 4000: phaseA_PNV.append(d1['bus']) print('.....................................................') print('The total number of nodes with PNV > 2000 and PNV < 4000 = ', len(set(phaseA_PNV))) print("timestamp: {} and the set of buses are: {}".format( timestamp, set(phaseA_PNV))) print(sh) # Open one of the switches if self._flag == 0: swmrid = '_BC63E102-37AD-4269-BB19-8351403B9B60' self._open_diff.add_difference( swmrid, "Switch.open", 1, 0) # (1,0) -> (current_state, next_state) msg = self._open_diff.get_message() print(msg) # send the message to platform self._gapps.send(self._publish_to_topic, json.dumps(msg)) swmrid = '_7262F9C3-2E8B-4069-AA13-BF4A655ACE35' self._open_diff.add_difference(swmrid, "Switch.open", 0, 1) msg = self._open_diff.get_message() print(msg) self._gapps.send(self._publish_to_topic, json.dumps(msg)) self._flag = 1
class NodalVoltage(object): """ A simple class that handles publishing forward and reverse differences Important in handling the gridappsd platform The object should be used as a callback from a GridAPPSD object so that the on_message function will get called each time a message from the simulator. During the execution of on_message the `CapacitorToggler` object will publish a message to the simulation_input_topic with the forward and reverse difference specified. """ 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 on_message(self, headers, message): # this section is modified by shiva """ Handle incoming messages on the simulation_output_topic for the simulation_id Parameters ---------- headers: dict A dictionary of headers that could be used to determine topic of origin and other attributes. message: object A data structure following the protocol defined in the message structure of ``GridAPPSD``. Most message payloads will be serialized dictionaries, but that is not a requirement. """ if type(message) == str: message = json.loads(message) # Some demo for understanding object and measurement mrids. # Print the status of several switches timestamp = message["message"]["timestamp"] meas_value = message['message']['measurements'] print(self._obj_msr_reg) print(sh) # *************************** Regulator ******************************** # get the operating position of regulator reg_position = [d for d in self._obj_msr_reg if d['type'] == 'Pos'] #print ("\n ******* reg_position ********* \n ") #print(reg_position) #print(sh) # Store the regulator positions regulators_tap = [] for iter_reg_pos in reg_position: if iter_reg_pos['measid'] in meas_value: v = iter_reg_pos['measid'] p = meas_value[v] regulators_tap.append(p) print('\n................. regulator tap ...............\n') #print('The total regulators', len(set(regulators_tap))) #print(timestamp, set(regulators_tap)) #print(regulators_tap) # print (sh) # changing the tap position of the regulator reg_mrid = [x for x in regulators_tap if x['value'] == 0] print(reg_mrid) #print(sh) print("################ self regulators #####################") print(self._regulators) measid = [d for d in self._regulators if d['name'] == 'creg2a'] print("############# measid ###############") print(measid[0]['mrid']) print('############# measidtype ###############') print(type(measid[0])) self._tap_close_diff.add_difference(measid[0]['mrid'], "TapChanger.step", 5, 0) # send the message to platform msg = self._tap_close_diff.get_message() print(msg) self._gapps.send(self._publish_to_topic, json.dumps(msg)) #print(sh) # *************************** SWITCHES ******************************** # Find interested mrids. We are only interested in Pos of the switches switch_position = [ d for d in self._obj_msr_loadsw if d['type'] == 'Pos' ] #print ("\n ******* switch_position ********* \n ") #print(switch_position) # Store the open switches Loadbreak = [] for iter_sw_pos in switch_position: if iter_sw_pos['measid'] in meas_value: v = iter_sw_pos['measid'] p = meas_value[v] if p['value'] == 0: Loadbreak.append(iter_sw_pos['eqname']) print('.....................................................') print('The total number of open switches:', len(set(Loadbreak))) print(timestamp, set(Loadbreak)) print( "For now we can only allow you to view Phase-to-Neutral Voltage related information" ) phase_checking = ['A', 'B', 'C'] while (self.check): while not (self.inp): phase_val = input( "Which phase are you interested in (A/B/C)? ") self.inp = True if phase_val in phase_checking else print( 'Unidentified phase') print("Selecting Phase as ** {} ** -- ...".format(phase_val)) time.sleep(3) # PNV # Find interested mrids. We are only interested in PNV of specific phase phase_check = [d for d in self._ACline if d['phases'] == phase_val] # print ("\n ******* phase check ********* \n ") # print (phase_check) # print(sh) # get the ranges min_volt = float( input("Minimum value of voltage at phase {}? ".format( phase_val))) max_volt = float( input("Maximum value of voltage at phase {}? ".format( phase_val))) phase_PNV = [] for d1 in phase_check: if d1['measid'] in meas_value: v = d1['measid'] p = meas_value[v] # print ('\n p \n', p) # print(sh) if p['magnitude'] > min_volt and p['magnitude'] < max_volt: phase_PNV.append(d1['bus']) print('.....................................................') print('The total number of nodes with PNV > {} and PNV < {} = {} '. format(min_volt, max_volt, len(set(phase_PNV)))) print("timestamp: {} and the set of buses are: {}".format( timestamp, set(phase_PNV))) recheck = input("Do you want another option (Y/N)? ") if recheck == 'N': self.check = False self.inp = False # print(sh) self.check = True print('---------------------------------------') print("Now let's try working on the switches") print('---------------------------------------') switch_val = input( "Are you interesting in toggling the switches (Y/N)? ") # print("\n ************** check ********************* \n") # print(self._switches[0]['mrid']) #print(sh) if (switch_val == 'Y'): sel_sw = int(input("select the switch to toggle (0-7)")) # Open one of the switches if self._flag == 0: # swmrid = '_BC63E102-37AD-4269-BB19-8351403B9B60' # self._open_diff.add_difference(swmrid, "Switch.open", 1, 0) # (1,0) -> (current_state, next_state) # msg = self._open_diff.get_message() # print(msg) # send the message to platform # self._gapps.send(self._publish_to_topic, json.dumps(msg)) #swmrid = '_7262F9C3-2E8B-4069-AA13-BF4A655ACE35' #self._open_diff.add_difference(swmrid, "Switch.open", 0, 1) #msg = self._open_diff.get_message() #print(msg) #self._gapps.send(self._publish_to_topic, json.dumps(msg)) #self._flag = 1 swmrid = self._switches[sel_sw]['mrid'] self._open_diff.add_difference(swmrid, "Switch.open", 1, 0) # (1,0) -> (current_state, next_state) msg = self._open_diff.get_message() print(msg) # send the message to platform self._gapps.send(self._publish_to_topic, json.dumps(msg))
class SwitchingActions(object): """ A simple class that handles publishing forward and reverse differences The object should be used as a callback from a GridAPPSD object so that the on_message function will get called each time a message from the simulator. During the execution of on_meessage the `CapacitorToggler` object will publish a message to the simulation_input_topic with the forward and reverse difference specified. """ def __init__(self, simulation_id, gridappsd_obj, switches, msr_mrids_loadsw, msr_mrids_demand, demand, line): """ 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._store = [] 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.msr_mrids_loadsw = msr_mrids_loadsw self.msr_mrids_demand = msr_mrids_demand self.LineData = line self.DemandData = demand self.switches = switches self.TOP = [] self.flag_res = 0 _log.info("Building cappacitor list") def on_message(self, headers, message): """ Handle incoming messages on the simulation_output_topic for the simulation_id Parameters ---------- headers: dict A dictionary of headers that could be used to determine topic of origin and other attributes. message: object A data structure following the protocol defined in the message structure of ``GridAPPSD``. Most message payloads will be serialized dictionaries, but that is not a requirement. """ self._message_count += 1 flag_fault = 0 flag_event = 0 # Checking the topology everytime communicating with the platform if self.flag_res == 0: top = Topology(self.msr_mrids_loadsw, self.switches, message, self.TOP, self.LineData) TOP, flag_event = top.curr_top() self.TOP = TOP #Locate fault if flag_event == 1: flag_fault, fault = top.locate_fault() # Get consumer loads from platform # Not always working so commenting it for now # if self.flag_load == 0: # ld = PowerData(self.msr_mrids_demand, message) # ld.demand() # self.flag_load = 1 # Isolate and restore the fault if flag_fault == 1 and self.flag_res == 0: print('Forming the optimization problem.........') res = Restoration() op, cl, = res.res9500(self.LineData, self.DemandData, fault) # print (op, cl) sw_oc = SW_MRID(op, cl, self.switches, self.LineData) op_mrid, cl_mrid = sw_oc.mapping() # print (op_mrid) # print(cl_mrid) # Now reconfiguring the test case in Platform based on obtained MRIDs to mimic black sky event for sw_mrid in op_mrid: self._open_diff.add_difference(sw_mrid, "Switch.open", 1, 0) msg = self._open_diff.get_message() self._gapps.send(self._publish_to_topic, json.dumps(msg)) for sw_mrid in cl_mrid: self._open_diff.add_difference(sw_mrid, "Switch.open", 0, 1) msg = self._open_diff.get_message() self._gapps.send(self._publish_to_topic, json.dumps(msg)) self.flag_res = 1 print('Event #1 Successfully restored......')