Neste tutorial veremos como fazer chamadas HTTP GET ou POST utilizando os recursos de script do ScadaBR 1.2 (scripting, data point meta, etc). Este tipo de chamada pode ser utilizado para, por exemplo, enviar mensagens através da API do Telegram e de outros softwares.
Ainda não está usando o ScadaBR 1.2? Está esperando o que? Baixe já!
Funcionamento dos scripts no ScadaBR
O ScadaBR é um software construído, em seu núcleo, utilizando a linguagem Java. Entretanto, alguns recursos como o data point meta e a página de Scripting utilizam-se de um sistema de programação via scripts Javascript.
Sim, até os nomes Java e Javascript são parecidos, mas trata-se de duas linguagens diferentes. Então, como é que um programa escrito em Java pode executar código escrito em outra linguagem (Javascript)? É aí que entra uma biblioteca chamada Rhino, que é responsável por interpretar o código Javascript e converter para instruções que possam ser executadas pela Máquina Java.
Assim, os scripts do ScadaBR utilizam a sintaxe definida pela Rhino, que é uma espécie de híbrido entre Javascript e Java. Você pode escrever a maioria das instruções utilizando uma sintaxe normal de Javascript, mas existe a possibilidade de acessar e instanciar classes Java como se fossem objetos Javascript. Essa é uma parte mais técnica e complexa, então, não entrarei em detalhes aqui para não perder o foco do tutorial.
O mais importante a entender agora é que, como a Rhino é executada no lado do servidor (server side), você não terá acesso a algumas coisas que são implementadas apenas no lado do cliente, pelo DOM do navegador. Entre elas estão os objetos XMLHttpRequest, o que nos obriga a realizar chamadas GET/POST por outros métodos.
Chamadas GET e POST
Uma vez que não temos como utilizar XMLHttpRequest, utilizaremos a biblioteca Apache HttpClient, que já vem incluída no ScadaBR 1.2. Para facilitar, eu já criei duas funções que fazem esse processo automaticamente. Então, para implementar chamadas GET ou POST no ScadaBR 1.2, basta copiar no seu script a função simpleGet(URL, parameters)
ou simplePost(URL, parameters)
. O código de ambas está logo abaixo.
Para invocar essas funções no seu script, a sintaxe é bastante simples. Você deve fornecer um parâmetro URL
com uma string contendo a URL do site a ser requisitado. Além disso, para especificar quais parâmetros serão incluídos na requisição, você pode criar um array contendo objetos. Cada objeto desse array representa um parâmetro da sua requisição GET/POST e deve incluir uma entrada key
, contendo o parâmetro requisitado, e uma entrada value
, contendo seu respectivo valor.
Por exemplo, se quiséssemos fazer uma chamada GET para o site httbin.org/get
passando como parâmetros name=ScadaBR
e tutorial=GET
, poderíamos escrever o código assim:
// Definindo os parâmetros da requisição
var params = [ { key: "name", value: "ScadaBR" }, { key: "tutorial", value: "GET" } ];
// Salvar resposta num objeto
var obj = simpleGet("httbin.org/get", params);
Como você pode ter observado, as funções simpleGet()
e simplePost()
retornam um objeto. Este objeto pode ser utilizado para recuperar dados no seu código e possui as seguintes propriedades:
// Salvar resposta num objeto
var obj = simpleGet("httbin.org/get", params);
// Para acessar o código da requisição HTTP, use .status
obj.status; // Valor numérico
// Para acessar a resposta do servidor, use .response
obj.response; // String. Cuidado: pode conter null!
// Para acessar mensagens de erro (se houver), use .errors
obj.errors; // String. Cuidado: pode conter null!
Uma lógica simples para testar se a requisição deu certo poderia ser assim:
// Salvar resposta num objeto
var obj = simpleGet("httbin.org/get", params);
// Verificar se o status é OK (200)
if (obj.status == 200) {
// Pegar resposta
return obj.response;
} else {
// Pegar mensagens de erro
return obj.errors;
}
Código da função simpleGet()
Copie o seguinte código para implementar a função simpleGet()
e fazer chamadas GET nos seus scripts:
function simpleGet(url, parameters) {
var respStatus = null;
var respString = null;
var respErrors = null;
// Add parameters to the GET Url
var getUrl = url.replace(/\/$/, "") + "?";
for (var i in parameters) {
var paramKey = encodeURIComponent(parameters[i].key);
var paramValue = encodeURIComponent(parameters[i].value);
getUrl += paramKey + "=" + paramValue + "&";
}
// Java classes to import
var imports = JavaImporter(org.apache.commons.httpclient.HttpClient,
org.apache.commons.httpclient.methods.GetMethod,
org.apache.commons.httpclient.DefaultHttpMethodRetryHandler,
org.apache.commons.httpclient.params.HttpMethodParams
);
// Use Rhino's "with" feature
with (imports) {
var client = new HttpClient();
// Create a method instance.
var method = new GetMethod(getUrl);
// Provide custom retry handler is necessary
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
try {
// Execute the method.
var statusCode = client.executeMethod(method);
// Save the HTTP status to the response
respStatus = statusCode;
if (statusCode != 200) {
// Add error messages to the response
respErrors = "Method failed: " + String(method.getStatusLine());
} else {
// Read the response body.
var responseBody = method.getResponseBodyAsString();
// Deal with the response.
// Use caution: ensure correct character encoding and is not binary data
respString = String(responseBody);
}
} catch (e) {
// Add error messages to the response
respErrors = "Error occurred: " + String(e);
} finally {
// Release the connection.
method.releaseConnection();
}
}
// Return a Javascript object with the response data
return { status: respStatus, response: respString, errors: respErrors };
}
Código da função simplePost()
Copie o seguinte código para implementar a função simplePost()
e fazer chamadas POST nos seus scripts:
function simplePost(url, parameters) {
var respStatus = null;
var respString = null;
var respErrors = null;
// Java classes to import
var imports = JavaImporter(org.apache.commons.httpclient.HttpClient,
org.apache.commons.httpclient.methods.PostMethod,
org.apache.commons.httpclient.NameValuePair,
org.apache.commons.httpclient.DefaultHttpMethodRetryHandler,
org.apache.commons.httpclient.params.HttpMethodParams
);
// Use Rhino's "with" feature
with (imports) {
var client = new HttpClient();
// Create a method instance.
var method = new PostMethod(url);
// Add parameters to the POST request
var getUrl = url + "?";
for (var i in parameters) {
var paramKey = parameters[i].key;
var paramValue = parameters[i].value;
method.addParameter(paramKey, paramValue);
}
// Provide custom retry handler is necessary
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
try {
// Execute the method.
var statusCode = client.executeMethod(method);
// Save the HTTP status to the response
respStatus = statusCode;
if (statusCode != 200) {
// Add error messages to the response
respErrors = "Method failed: " + String(method.getStatusLine());
} else {
// Read the response body.
var responseBody = method.getResponseBodyAsString();
// Deal with the response.
// Use caution: ensure correct character encoding and is not binary data
respString = String(responseBody);
}
} catch (e) {
// Add error messages to the response
respErrors = "Error occurred: " + String(e);
} finally {
// Release the connection.
method.releaseConnection();
}
}
// Return a Javascript object with the response data
return { status: respStatus, response: respString, errors: respErrors };
}
Tutorial em vídeo
Se dizem que uma imagem vale mais do que mil palavras, então um vídeo deve ter um valor ainda maior. Para finalizar deixarei aqui um excelente tutorial feito pelo Fernando José, da empresa Branqs, em que ele ensina como utilizar essas funções para integrar o ScadaBR ao Telegram. E de quebra você ainda pode aprender a criar uma instância do ScadaBR no Linux!