Algoritmo de funcionamento do framework Python#

O script do framework Python, executado pelo Agendador do Windows, deve seguir o seguinte algoritmo:

  1. Realizar uma requisição HTTP POST para o script /api/robot/heartbeat do Orquestrador. Passar nos parâmetros:
    1. GUID deste Robô (RobotGUID),
    2. nome do computador (Machine),
    3. endereço IP da máquina (IP),
    4. endereço MAC da máquina (MAC),
    5. status atual do Robô (Status),
    6. GUID do Trabalho que está sendo executado no momento (JobGUID),
    7. nome do Trabalho que está sendo executado no momento (JobName),
    8. tipo de Trabalho (JobType, sempre deve ter o tipo Orchestrated, valor 1).

Os dados de saída (no formato JSON):

  • HeartbeatErrorCode,
  • ErrorText,
  • HasNewJob.

O script pode retornar outros parâmetros na resposta que não são utilizados no contexto da Tarefa atual.

Dicionário de status dos Robôs:

Status_Disconnected = 0; # robô desconectado
Status_Unlicensed     = 1; # robô não licenciado
Status_Ready        = 2; # robô não está executando trabalhos e está pronto para receber novos trabalhos
Status_Working    = 3; # robô está executando o trabalho atual

Dicionário de valores ErrorCode:

HeartbeatErrorCode_NoError = 0;  # sem erros
HeartbeatErrorCode_RobotNotFound = 101;  # robô com o GUID especificado não encontrado
HeartbeatErrorCode_JobAborting = 10;   # orquestrador solicitou a parada forçada deste script (Abort)
HeartbeatErrorCode_JobStopping = 20;   # orquestrador solicitou a parada suave deste script (Stop)

Dicionário de valores HasNewJob:

HasNewJob_NoJob = 0 # para este robô não há novos trabalhos
HasNewJob_JobFound = 1 # para este robô há novos trabalhos que precisam ser obtidos com a chamada ConsumeNextJob

Na primeira execução do script, deve-se passar o valor Status = 2 (Status_Ready). Também na primeira execução, quando o nome e o GUID do trabalho em execução ainda são desconhecidos, esses campos podem permanecer vazios.

Exemplo de chamada:

import requests
import base64
import json

from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
host = 'http://192.168.1.111:4500' #host do orquestrador
robot_guid = 'da8bc2f0-8065-4385-b867-405e66b8e151' #GUID do robô
headers = {
    'Authorization': 'Basic ' + base64.b64encode(robot_guid.encode('utf-8')).decode('utf-8')
}
req = {
    'RobotGUID': robot_guid,   #GUID do robô
    'Machine': robot_machine,   #Nome da máquina
    'IP': robot_ip,   #Endereço IP do robô
    'MAC': robot_mac,   #Endereço MAC do robô
    'Status': 2,   #status do robô
    'JobGUID': '',  #GUID do trabalho
    'JobName': '',   #nome do script em execução, ou seja, python_script_name adiante no texto
    'JobType': 1   #tipo de trabalho, sempre valor 1
}
r = requests.post(host + '/api/robot/heartbeat', data=req, headers=headers, verify=False)
heartbeat_results = json.loads(r.text)
print(heartbeat_results ['HeartbeatErrorCode'])
print(heartbeat_results ['ErrorText'])
print(heartbeat_results ['HasNewJob'])
  1. Caso a resposta seja HasNewJob == 0, encerrar a execução do script do framework e sair da conta do Windows usando Log off.

    Caso a resposta seja HasNewJob == 1, realizar uma requisição HTTP POST para o script /api/robot/consumeNextJob do Orquestrador.

    Dados de entrada:

    1. GUID do Robô (RobotGUID),
    2. status atual do Robô (Status).


    Dados de saída (no formato JSON):

    1. ConsumeJobErrorCode,
    2. ErrorText,
    3. Job,
    4. ProcessVersion,
    5. Task.

    Dicionário de valores ConsumeJobErrorCode:

    ConsumeJobErrorCode = 0; # sem erros
    ConsumeJobErrorCode = 101; # robô com o GUID especificado não encontrado
    ConsumeJobErrorCode = 102; # novo trabalho não encontrado

    Exemplo de chamada:

    import requests
    import base64
    import json

    from requests.packages.urllib3.exceptions import InsecureRequestWarning
    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

    host = 'http://192.168.1.111:4500' #host do orquestrador
    robot_guid = 'da8bc2f0-8065-4385-b867-405e66b8e151' #GUID do robô

    headers = {
    'Authorization': 'Basic ' + base64.b64encode(robot_guid.encode('utf-8')).decode('utf-8')
    }

    cnj = {
    'RobotGUID': robot_guid #GUID do robô
    }

    r = requests.post(host + '/api/robot/consumeNextJob', data=cnj, headers=headers, verify=False)
    consume_result = json.loads(r.text)
    print(consume_result['ConsumeJobErrorCode'])
    print(consume_result['ErrorText'])
    new_job = json.loads(consume_result['Job'])
    job_guid = new_job['GUID']
    process_version = json.loads(consume_result['ProcessVersion'])
    python_script_name = process_version['Name'] #Convenhamos que o nome do script do robô que deve ser executado é passado no nome da versão do processo
    task = json.loads(consume_result[' Task '])

  2. Em caso de sucesso na obtenção de um novo Trabalho do Orquestrador, realizar uma requisição HTTP PUT para o script /api/job/update do Orquestrador. Passar nos parâmetros o GUID do Trabalho obtido (guid) e o novo status do Trabalho Status_In_Progress.

    Dicionário de valores dos status dos Trabalhos:

    Status_Created = 0; #Trabalho criado
    Status_Pending = 1; #Trabalho aguardando que o robô o pegue para execução
    Status_Aborting = 2; #Trabalho em fase de parada forçada (interrupção)
    Status_Aborted = 3; #Trabalho interrompido com sucesso
    Status_Success = 4; #Trabalho concluído com sucesso
    Status_Failed = 5; #Trabalho não concluído com sucesso
    Status_Stopping = 6; #Trabalho em fase de parada suave
    Status_Stopped = 7; #Trabalho parado com sucesso após solicitação de parada suave
    Status_In_Progress = 8; #Trabalho está sendo executado no momento

    Exemplo de chamada:

    import requests
    import base64
    import json

    from requests.packages.urllib3.exceptions import InsecureRequestWarning
    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
    host = 'http://192.168.1.111:4500' #host do orquestrador
    robot_guid = 'da8bc2f0-8065-4385-b867-405e66b8e151' #GUID do robô

    headers = {
    'Authorization': 'Basic ' + base64.b64encode(robot_guid.encode('utf-8')).decode('utf-8')
    }

    job = {
    'guid': job_guid, #GUID do trabalho atual
    'status': 8 #novo status do trabalho
    }

    r = requests.put(host + '/api/job/update', data=job, headers=headers, verify=False)
    print(r.text)

  3. Iniciar a execução do script Python do Robô com o nome igual a python_script_name. Sempre que possível, repetir periodicamente as requisições para o script /api/robot/heartbeat com o valor correto de JobGUID e Status = 3 (Status_Working).

    Recomenda-se enviar essa requisição não mais do que uma vez a cada 10 segundos. Caso a resposta retorne o status HeartbeatErrorCode == 10, é necessário interromper imediatamente a execução do script Python do Robô.

    Caso a resposta retorne o status HeartbeatErrorCode == 20, é necessário realizar o encerramento correto do script Python do Robô.

  4. Após a conclusão do script Python do Robô, realizar uma requisição HTTP PUT para o script /api/job/update do Orquestrador. Passar nos parâmetros o GUID do Trabalho atual do Robô (guid) e o novo status do Trabalho dependendo do resultado de sua conclusão, conforme o dicionário apresentado acima.

  5. Em seguida, realizar uma requisição HTTP POST para o script /api/robot/heartbeat do Orquestrador com o status Status = 2 (Status_Ready) e retornar ao passo 2 do algoritmo do framework.