def async_cfp(): # Message to send message = ACLMessage() message.set_content('Send me proposals, please!') for r in recipients_aid: message.add_receiver(r) self.contract_net.send_cfp(message) proposals_received = [] while True: try: # Expecting PROPOSAL by default proposal = yield message display_message( self.aid.name, f'I received PROPOSE: {proposal.content} from {proposal.sender.name}' ) proposals_received.append(proposal) except FipaRefuseHandler as h: refusal = h.message display_message( self.aid.name, f'I received REFUSE: {refusal.content} from {refusal.sender.name}' ) except FipaCfpComplete: break try: best_value = max(int(m.content) for m in proposals_received) except ValueError: display_message(self.aid.name, f'No proposals!') return best_proposal = next(m for m in proposals_received if int(m.content) == best_value) # Reject message for message in filter(lambda m: m != best_proposal, proposals_received): reply = message.create_reply() reply.set_content('Rejected, sorry!') # It does not create a session self.contract_net.send_reject_proposal(reply) # Accept message reply = best_proposal.create_reply() reply.set_content('Accepted!') # It creates a session self.contract_net.send_accept_proposal(reply) try: # Expects INFORM by default inform = yield reply content = inform.content display_message( self.aid.name, f'I received INFORM: {content} from {inform.sender.name}') except FipaFailureHandler as h: failure = h.message
def on_request(self, message: ACLMessage): content = message.content display_message(self.aid.name, f'I received REQUEST: {content} from {message.sender.name}') reply = message.create_reply() reply.set_content(str(eval(content))) self.calculator_behaviour.send_inform(reply)
def handle_subscribe(self, message: ACLMessage): """Permite o cadastro de assinantes (em especial, o ADC) para que recebam mensagens relativas à ocorrência de uma falta""" display_message(self.aid.name, f"New subscriber: {message.sender.name}") self.behaviours_enviodedados.subscribe(message) # Criar resposta de aceite reply = message.create_reply() self.behaviours_enviodedados.send_agree(reply)
def on_message(self, message: ACLMessage): content = json.loads(message.content) display_message(self.aid.name, content) reply = message.create_reply() reply.set_content( json.dumps({ 'outputVariable': content['inputVariable'] * 2 + 2 * content['current_time'] })) self.fmi_adapter.inform(reply)
def on_message(self, message: ACLMessage): display_message(self.aid.name, f'Received message: {message.content}') content = json.loads(message.content) pprint(content) reply = message.create_reply() reply.set_content( json.dumps({ 'output': str(content['input'] * 2 + 2 * content['current_time']) })) self.fmi_adapter.inform(reply)
def on_request(self, message: ACLMessage): display_message(self.aid.name, "Received a message") reply = message.create_reply() reply.set_content(f'Take this! {random()}') delay = 10 * random() display_message(self.aid.name, "Starting job") print('Job delay:', delay) if random() < 0.5: call_later(delay, self.req.send_inform, reply) else: call_later(delay, self.req.send_failure, reply)
def handle_request(self, message: ACLMessage): if message.ontology == "R_05": # Será recebida uma poda por vez poda_cim = message.content poda = rdf2mygrid.cim_poda(poda_cim) # poda = pickle.loads(poda_cim) display_message(self.aid.name, "Mensagem REQUEST Recebida") resposta = message.create_reply() resposta.set_performative(ACLMessage.AGREE) resposta.set_ontology("R_05") self.send(resposta) self.preparar_negociacao(poda, message)
def handle_cfp(self, message: ACLMessage): display_message(self.aid.name, "Mensagem CFP recebida") setores_colab = dict() # Carrega conteudo da mensagem poda_cim = message.content poda = rdf2mygrid.cim_poda(poda_cim) # poda = pickle.loads(poda_cim) # Busca o possivel alimentador e setor de recomposicao do ramo for alim in self.topologia_subestacao.alimentadores: for chave in poda[6]: if chave in self.topologia_subestacao.alimentadores[ alim].chaves: if self.topologia_subestacao.alimentadores[alim].chaves[ chave].n1.nome in self.topologia_subestacao.alimentadores[ alim].setores: setor_colab = self.topologia_subestacao.alimentadores[ alim].chaves[chave].n1.nome setores_colab[setor_colab] = chave elif self.topologia_subestacao.alimentadores[alim].chaves[ chave].n2.nome in self.topologia_subestacao.alimentadores[ alim].setores: setor_colab = self.topologia_subestacao.alimentadores[ alim].chaves[chave].n2.nome setores_colab[setor_colab] = chave if len( setores_colab ): # Se houver mais de um possivel caminho de restauracao para este ramo # Inicia variaveis auxiliares aux = 0 setor_colab = None alim_colab = None # Para cada um dos possiveis setores colaboradores # busca aquele mais profundo a fim de tentar recompor a poda for setor in setores_colab: alim = self.find_sector(setor) rnp_alim = self.topologia_subestacao.alimentadores[ alim].rnp_dic() if int(rnp_alim[setor]) > aux: aux = int(rnp_alim[setor]) setor_colab = setor alim_colab = alim setores = self.topologia_subestacao.alimentadores[ alim_colab].setores chaves = self.topologia_subestacao.alimentadores[alim_colab].chaves chave_ligacao = next(chave for chave in chaves if chave in poda[6]) # Verifica qual o setor raiz de insercao da poda for setor in setores: for set_vizinho in setores[setor].vizinhos: if set_vizinho in poda[0]: setor_interno = setor setor_raiz = set_vizinho ### Atualiza poda com informações internas # Setores poda[0][setor_raiz].rnp_associadas[setor_interno] = setores[next( v for v in setores[setor_interno].vizinhos if v != setor_raiz)].rnp_associadas[setor_interno] poda[0][setor_raiz].vizinhos.append(setor_interno) poda[0][setor_raiz].rnp_associadas.pop('alimentador') poda[0][setor_raiz].vizinhos.remove('alimentador') # Nos no_raiz = next(no for no in poda[0][setor_raiz].nos_de_carga.values() if 'barramento_falso' in no.vizinhos) no_raiz.vizinhos.append( next(no.nome for no in setores[setor_interno].nos_de_carga.values() if no_raiz.nome in no.vizinhos)) no_raiz.vizinhos.remove('barramento_falso') poda[0][setor_raiz].rnp_associadas[setor_interno] = ( poda[0][setor_raiz].rnp_associadas[setor_interno][0], poda[5]) # Chaves poda[6][chave_ligacao].n1 = chaves[chave_ligacao].n1 poda[6][chave_ligacao].n2 = chaves[chave_ligacao].n2 # Envia poda e possiveis setores de restauracao neste alimentador # para que a poda seja inserida e testada retornando qual foi # a possivel colaboracao do alimentador dados = self.inserir_poda_testar(poda, setor_colab) if len(dados["setores"]) != 0: response = yield from self.send_proposal(cfp_message=message, data=dados) if response.performative == ACLMessage.ACCEPT_PROPOSAL: yield from self.recompor_se_externa(response) return else: display_message( self.aid.name, f"Nao foi possível restaurar o ramo pela {self.substation}" ) else: # Se nao houver setores para possivel colaboracao ramo = list(poda[0].keys()) display_message( self.aid.name, f"SE [{self.substation}] nao possui chave de encontro com o ramo {ramo}" ) # Elabora Mensagem de Refuse para o agente iniciante resposta = message.create_reply() resposta.set_ontology("CN_02") resposta.set_content(None) self.resp_negotiation.send_refuse(resposta)
def solicitar_propostas(self, poda): """Define função que será chamada após cada resposta""" poda_cim = rdf2mygrid.poda_cim(poda) # poda_cim = pickle.dumps(poda) # Elabora mensagem message = ACLMessage(ACLMessage.CFP) message.set_protocol(ACLMessage.FIPA_CONTRACT_NET_PROTOCOL) message.set_ontology("CN_01") message.set_content(poda_cim) for aid in self.adc_vizinhos: message.add_receiver(aid) propostas_realizaveis = [] while True: try: proposta = yield from self.manage_negotiation_behaviour.send_cfp( message) display_message( self.aid.name, f"Mensagem PROPOSE recebida de {proposta.sender.name}") content = json.loads(proposta.content) proposta_realizavel = (content["setores"] != []) if proposta_realizavel: # Salva proposta para mais tarde propostas_realizaveis.append(proposta) else: # Rejeita proposta imediatamente name = message.sender.localname ramo = proposta.content display_message( self.aid.name, f"Agente {name} possui chave de encontro, mas nao pode colaborar para o ramo {ramo}." ) reject_message = proposta.create_reply() reject_message.set_ontology("CN_05") reject_message.set_content('Proposta não realizável') self.manage_negotiation_behaviour.send_reject_proposal( reject_message) except FipaRefuseHandler as h: refusal = h.message display_message( self.aid.name, f"Mensagem REFUSE recebida de {refusal.sender.name}") except FipaCfpComplete: break # Dados da melhor proposta melhor_proposta = None setores_atendidos = 0 # Escolha do melhor propositor sob algum criterio if self.criterios["carreg_SE"] and self.criterios["carga_prior"]: pass elif self.criterios["carreg_SE"] and self.criterios["perdas"]: pass elif self.criterios["carreg_SE"] and self.criterios["chaveamentos"]: pass # Apenas carregamento da SE e qtd de setores atendidos else: # Varre todas as propostas recebidas for message in propostas_realizaveis: display_message( self.aid.name, f"Analisando proposta {propostas_realizaveis.index(message) + 1} de {len(propostas_realizaveis)}" ) # Carrega conteudo da mensagem analisada content = json.loads(message.content) name = message.sender.name display_message( self.aid.name, f"Agente {name} pode restaurar ramo {content['setores']} com carregamento de {content['carreg_SE']}% da sua SE" ) # Verifica se atual proposta atende maior numero de setores if len(content["setores"]) > setores_atendidos: melhor_proposta = message setores_atendidos = len(content["setores"]) # Se atende o mesmo numero de setores, verifica carregamento elif len(content["setores"]) == setores_atendidos: content_melhor_atual = json.loads(message.content) # Se carregamento atual for maior, vira melhor proposta if content["carreg_SE"] > content_melhor_atual["carreg_SE"]: melhor_proposta = message setores_atendidos = len(content["setores"]) # Envia Reject-Proposal para demais agentes for message in propostas_realizaveis: if message is melhor_proposta: continue resposta = message.create_reply() resposta.set_ontology("CN_04") self.manage_negotiation_behaviour.send_reject_proposal(resposta) # Envia Accept-Proposal para Agente Ganhador if melhor_proposta is not None: resposta = melhor_proposta.create_reply() resposta.set_ontology("CN_04") resposta.set_content(melhor_proposta.content) while True: try: result = yield from self.manage_negotiation_behaviour.send_accept_proposal( resposta) display_message(self.aid.name, "Mensagem INFORM Recebida") except FipaFailureHandler as h: result = h.message display_message(self.aid.name, "Mensagem FAILURE Recebida") except FipaProtocolComplete: break return result else: display_message(self.aid.name, "Nenhuma proposta foi acatada.") return None
def handle_request(self, message: ACLMessage): """Recepção de mensagem de comando (conteúdo deve ser um SwitchingCommand) OBS: Mensagem recebida deve ser processada e respondida com agree / refuse / not_understood""" # Esperado SwitchingCommand if message.ontology != swc.__name__: reply = message.create_reply() reply.set_ontology('') reply.set_content( f'{GeneralError.UnexpectedOntology.value}: {message.ontology}') self.behaviours_recebercomando.send_not_understood(reply) return # Lista que armazena ações requisitadas buffer_leitura_acoes = [] # Lê documento recebido try: # Recupera instância SwitchingCommand ("cast" para dar uma dica pro Intellisense [Ctrl+Space]) root: swc.SwitchingCommand = \ swc.parseString(to_string(message.content)) # Iterar em lista de SwitchAction for switchAction in root.get_SwitchingPlan().get_SwitchAction(): switchId = switchAction.get_OperatedSwitch().get_mRID() actionKind = switchAction.get_kind() sequenceNumber = switchAction.get_sequenceNumber() buffer_leitura_acoes.append( (sequenceNumber, switchId, actionKind)) except Exception as e: # Captura erro de má formatação do documento. # Devolve uma mensagem not_understood e finaliza reply = message.create_reply() reply.set_content(f'{GeneralError.BadFormatting.value}: {e}') self.behaviours_recebercomando.send_not_understood(reply) return # Ordena por sequenceNumber buffer_leitura_acoes.sort(key=lambda item: item[0]) # Realiza ações try: for sequenceNumber, switchId, actionKind in buffer_leitura_acoes: self.comandar_chave(switchId, actionKind) # Retorna sucesso reply = message.create_reply() reply.set_content(CommandResult.Success.value) self.behaviours_recebercomando.send_inform(reply) except SwitchAlreadyInPosition as e: # Retorna sucesso, mas nenhuma operação foi realizada reply = message.create_reply() reply.set_content(f'{CommandResult.AlreadyInPosition.value}: {e}') self.behaviours_recebercomando.send_inform(reply) except KeyError as e: # Retorna falha ao não encontrar switchId reply = message.create_reply() reply.set_content(f'{CommandResult.NotFound.value}: {e}') self.behaviours_recebercomando.send_failure(reply) except Exception as e: # Retorna falha genérica desconhecida reply = message.create_reply() reply.set_content(f'{CommandResult.Unknown.value}: {e}') self.behaviours_recebercomando.send_failure(reply)