Algoritmo de funcionamento do framework Python#
O script do framework Python, executado pelo Agendador do Windows, deve seguir o seguinte algoritmo:
- Realizar uma requisição HTTP POST para o script
/api/robot/heartbeatdo Orquestrador. Passar nos parâmetros:- GUID deste Robô (RobotGUID),
- nome do computador (Machine),
- endereço IP da máquina (IP),
- endereço MAC da máquina (MAC),
- status atual do Robô (Status),
- GUID do Trabalho que está sendo executado no momento (JobGUID),
- nome do Trabalho que está sendo executado no momento (JobName),
- 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'])
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 sejaHasNewJob == 1, realizar uma requisição HTTP POST para o script/api/robot/consumeNextJobdo Orquestrador.
Dados de entrada:- GUID do Robô (RobotGUID),
- status atual do Robô (Status).
Dados de saída (no formato JSON):- ConsumeJobErrorCode,
- ErrorText,
- Job,
- ProcessVersion,
- Task.
Dicionário de valores ConsumeJobErrorCode:
ConsumeJobErrorCode = 0; # sem errosConsumeJobErrorCode = 101; # robô com o GUID especificado não encontradoConsumeJobErrorCode = 102; # novo trabalho não encontrado
Exemplo de chamada:import requestsimport base64import jsonfrom requests.packages.urllib3.exceptions import InsecureRequestWarningrequests.packages.urllib3.disable_warnings(InsecureRequestWarning)host = 'http://192.168.1.111:4500' #host do orquestradorrobot_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 processotask = json.loads(consume_result[' Task '])Em caso de sucesso na obtenção de um novo Trabalho do Orquestrador, realizar uma requisição HTTP PUT para o script
/api/job/updatedo Orquestrador. Passar nos parâmetros o GUID do Trabalho obtido (guid) e o novo status do TrabalhoStatus_In_Progress.
Dicionário de valores dos status dos Trabalhos:Status_Created = 0; #Trabalho criadoStatus_Pending = 1; #Trabalho aguardando que o robô o pegue para execuçãoStatus_Aborting = 2; #Trabalho em fase de parada forçada (interrupção)Status_Aborted = 3; #Trabalho interrompido com sucessoStatus_Success = 4; #Trabalho concluído com sucessoStatus_Failed = 5; #Trabalho não concluído com sucessoStatus_Stopping = 6; #Trabalho em fase de parada suaveStatus_Stopped = 7; #Trabalho parado com sucesso após solicitação de parada suaveStatus_In_Progress = 8; #Trabalho está sendo executado no momento
Exemplo de chamada:import requestsimport base64import jsonfrom requests.packages.urllib3.exceptions import InsecureRequestWarningrequests.packages.urllib3.disable_warnings(InsecureRequestWarning)host = 'http://192.168.1.111:4500' #host do orquestradorrobot_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)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/heartbeatcom o valor correto deJobGUIDeStatus = 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 statusHeartbeatErrorCode == 10, é necessário interromper imediatamente a execução do script Python do Robô.
Caso a resposta retorne o statusHeartbeatErrorCode == 20, é necessário realizar o encerramento correto do script Python do Robô.Após a conclusão do script Python do Robô, realizar uma requisição HTTP PUT para o script
/api/job/updatedo 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.Em seguida, realizar uma requisição HTTP POST para o script
/api/robot/heartbeatdo Orquestrador com o statusStatus = 2 (Status_Ready)e retornar ao passo 2 do algoritmo do framework.