Skip to content

Repository files navigation

Instron Bridge SelfHost API

API local desenvolvida em C#/.NET Framework para fazer a ponte entre uma aplicação externa e o software Bluehill Universal da Instron.

A aplicação roda como um .exe SelfHost, sem depender do IIS, mantendo a conexão com o Bluehill ativa enquanto o programa estiver aberto.


1. Objetivo do projeto

O objetivo deste projeto é permitir que uma aplicação externa, como um sistema em PHP, consiga comunicar com o Bluehill Universal através de endpoints HTTP.

A API permite:

  • verificar se a aplicação está online;
  • conectar ao Bluehill;
  • obter o estado atual do Bluehill;
  • criar amostras;
  • iniciar e parar testes;
  • consultar resultados;
  • guardar e fechar amostras;
  • consultar medições;
  • gerar logs de teste.

2. Tecnologias utilizadas

  • C#
  • .NET Framework 4.7.2
  • ASP.NET Web API
  • OWIN SelfHost
  • Bluehill.API.dll
  • Postman
  • PHP/cURL para consumo externo

3. Arquitetura geral

Fluxo principal:

Aplicação PHP / Postman / Frontend
        ↓
InstronBridgeSelfHost.exe
        ↓
Bluehill.API.dll
        ↓
Bluehill Universal
        ↓
Máquina Instron

O .exe cria um pequeno servidor HTTP local na porta 9000.

Base URL padrão:

http://localhost:9000

4. Estrutura principal do projeto

InstronBridgeSelfHost
│
├── App_Start
│   └── WebApiConfig.cs
│
├── Callbacks
│   └── InstronCallback.cs
│
├── Controllers
│   └── InstronController.cs
│
├── InstronLogs
│   └── Logger.cs
│
├── Models
│   ├── CreateSampleRequest.cs
│   ├── SaveSampleRequest.cs
│   ├── PedidoBluehillDto.cs
│   └── InstronServiceState.cs
│
├── Services
│   └── InstronService.cs
│
├── Program.cs
├── Startup.cs
├── App.config
└── packages.config

5. Requisitos na máquina da Instron

A máquina onde o .exe será executado precisa ter:

Bluehill Universal instalado
Bluehill.API.dll disponível
.NET Framework 4.7.2 ou superior
Permissão para executar o Bluehill
Permissão para criar ficheiros de log

Também é importante executar o .exe como administrador, principalmente durante os testes iniciais.


6. Compilação do projeto

No Visual Studio:

Build → Configuration Manager

Selecionar:

Release
x86

Depois executar:

Build → Rebuild Solution

O projeto deve ser compilado em x86, porque a Bluehill.API.dll trabalha com arquitetura x86.


7. Publicação/execução na máquina da Instron

Após compilar, copiar todo o conteúdo da pasta:

bin\x86\Release

Para a máquina da Instron, por exemplo:

C:\InstronBridgeSelfHost

A estrutura final pode ficar assim:

C:\InstronBridgeSelfHost
│
├── InstronBridgeSelfHost.exe
├── InstronBridgeSelfHost.exe.config
├── Bluehill.API.dll
├── Microsoft.Owin.dll
├── Newtonsoft.Json.dll
├── outras DLLs...
└── InstronLogs

Executar:

InstronBridgeSelfHost.exe

De preferência:

Botão direito → Executar como administrador

A consola deve mostrar algo parecido com:

==========================================
 Instron Bridge API Self Host iniciado
==========================================

URL:
http://localhost:9000/

Importante: a janela da consola precisa permanecer aberta. Ela é o servidor da API.


8. Logs

Os logs são guardados dentro da pasta onde o .exe está a ser executado.

Exemplo:

C:\InstronBridgeSelfHost\InstronLogs\logs.txt

Durante o desenvolvimento, o caminho pode ser:

bin\x86\Release\InstronLogs\logs.txt

Exemplo de log:

2026-05-19 14:30:22 [INFO] SelfHost iniciado com sucesso.
2026-05-19 14:31:10 [INFO] Conectado ao Bluehill com sucesso.

9. Endpoints da API

Base URL:

http://localhost:9000/api/instron

9.1 Health Check

Verifica se a API está online e mostra informações sobre a conexão.

Request

GET /health

Exemplo

GET http://localhost:9000/api/instron/health

Response

{
  "status": "online",
  "connected": true,
  "lastState": "ReadyToStartTest",
  "lastStatusCode": null,
  "lastStatusMessage": "Conectado ao Bluehill com sucesso."
}

Para que serve

Este endpoint serve para verificar:

  • se a API está ligada;
  • se existe conexão com o Bluehill;
  • qual foi o último estado conhecido;
  • qual foi a última mensagem recebida.

9.2 Connect

Inicia o Bluehill, estabelece conexão com a API do Bluehill e mantém a referência em memória.

Request

POST /connect

Exemplo

POST http://localhost:9000/api/instron/connect

Body

Não precisa de body.

Response

{
  "message": "Conectado ao Bluehill com sucesso."
}

Observacao

Este endpoint pode ser usado para forcar a abertura/conexao manual durante testes. No fluxo operacional, os endpoints /state, /results, /results/formatted e /measurement tentam conectar automaticamente ao Bluehill quando ainda nao existe uma sessao valida.


9.3 State

Retorna o estado atual do Bluehill.

Request

GET /state

Exemplo

GET http://localhost:9000/api/instron/state

Response

{
  "state": "ReadyToStartTest"
}

Para que serve

Permite saber em que estado o Bluehill se encontra no momento.

Exemplos de estados possíveis:

BluehillStarting
BluehillHome
SampleOpened
ReadyToStartTest
Running
Calculating

9.4 Create Sample

Cria uma nova amostra no Bluehill a partir de um ficheiro de método.

Request

POST /create-sample

Exemplo

POST http://localhost:9000/api/instron/create-sample

Body

{
  "methodFilePath": "C:\\Users\\Public\\Documents\\Instron\\Bluehill Universal\\Templates\\metodo.im_tens"
}

Response

{
  "message": "Amostra criada com sucesso.",
  "result": "NoError"
}

Para que serve

Este endpoint é usado quando a aplicação externa precisa criar uma nova amostra no Bluehill com base num método existente.


9.5 Start Test

Inicia o teste atual no Bluehill.

Request

POST /start-test

Exemplo

POST http://localhost:9000/api/instron/start-test

Body

Não precisa de body.

Response

{
  "message": "Teste iniciado com sucesso.",
  "result": "NoError"
}

Atenção

Este endpoint pode movimentar a máquina física. Usar apenas com operador presente e com o ensaio preparado.


9.6 Stop Test

Para o teste em execução.

Request

POST /stop-test

Exemplo

POST http://localhost:9000/api/instron/stop-test

Body

Não precisa de body.

Response

{
  "message": "Teste parado com sucesso.",
  "result": "NoError"
}

Para que serve

Permite interromper um teste em andamento através da API.


9.7 Results

Obtém os dados da tabela de resultados e estatísticas da amostra atualmente aberta no Bluehill.

Request

GET /results?tableNumber=1

Exemplo

GET http://localhost:9000/api/instron/results?tableNumber=1

Response

{
  "tableNumber": 1,
  "data": [
    ["Specimen", "Peak Load", "Extension"],
    [1, 520.4, 12.8]
  ]
}

Observação importante

Este endpoint não devolve o histórico completo da máquina. Ele devolve os dados da tabela de resultados da amostra atualmente aberta no Bluehill.

Se retornar:

{
  "tableNumber": 1,
  "data": null
}

pode significar que:

  • não existe amostra aberta;
  • a tabela 1 está vazia;
  • o teste ainda não gerou resultados;
  • os resultados ainda não foram calculados;
  • a amostra aberta não possui resultados gravados.

9.8 Results Formatted

Obtem os mesmos resultados da tabela, mas devolve os dados em formato pronto para consumo por uma tabela no frontend.

Request

GET /results/formatted?tableNumber=1

Exemplo

GET http://localhost:9000/api/instron/results/formatted?tableNumber=1

Response

{
  "tableNumber": 1,
  "headers": ["Specimen", "Peak Load", "Extension"],
  "rows": [
    {
      "Specimen": 1,
      "Peak Load": 520.4,
      "Extension": 12.8
    }
  ]
}

Observacao

Este endpoint tambem tenta conectar/reconectar automaticamente ao Bluehill antes de consultar a tabela.


9.9 Save Sample

Guarda a amostra atual.

Request

POST /save-sample

Exemplo

POST http://localhost:9000/api/instron/save-sample

Body

{
  "filePath": "C:\\Users\\Public\\Documents\\Instron\\Bluehill Universal\\Samples\\amostra1.is_tens"
}

Response

{
  "message": "Amostra guardada com sucesso.",
  "result": "NoError"
}

Observação

Se o filePath for nulo, o Bluehill pode usar o caminho padrão.


9.10 Close Sample

Fecha a amostra atualmente aberta no Bluehill.

Request

POST /close-sample

Exemplo

POST http://localhost:9000/api/instron/close-sample

Body

Não precisa de body.

Response

{
  "message": "Amostra fechada com sucesso.",
  "result": "NoError"
}

9.11 Measurement

Obtém uma medição específica do Bluehill.

Request

GET /measurement?measurementName=NOME&unit=UNIDADE

Exemplo

GET http://localhost:9000/api/instron/measurement?measurementName=Load&unit=Newtons

Response

{
  "measurement": "Load",
  "unit": "Newtons",
  "value": 120.45
}

Observação

O nome da medição e a unidade precisam existir no Bluehill.


9.12 Disconnect

Fecha a conexao WCF da API e tenta encerrar o processo Bluehill. Se a janela nao responder, o processo e finalizado para evitar sessoes presas no Task Manager.

Request

POST /disconnect

Exemplo

POST http://localhost:9000/api/instron/disconnect

Body

Não precisa de body.

Response

{
  "message": "Conexao encerrada e processo Bluehill finalizado."
}

Observação

Este endpoint e util para testes e manutencao. No frontend operacional, nao e necessario expor botao de conectar/desconectar.


9.13 Teste

Endpoint simples para testar envio de JSON.

Request

POST /teste

Exemplo

POST http://localhost:9000/api/instron/teste

Body

{
  "nome": "Teste",
  "nif": "123456789",
  "email": "[email protected]"
}

Response

{
  "mensagem": "Dados recebidos com sucesso",
  "dados": {
    "nome": "Teste",
    "nif": "123456789",
    "email": "[email protected]"
  }
}

9.14 Teste Logs

Endpoint usado para testar a escrita de logs.

Request

POST /testeLogs

Exemplo

POST http://localhost:9000/api/instron/testeLogs

Body

{
  "nome": "Leonardo",
  "nif": "123456789",
  "email": "[email protected]"
}

Response

{
  "sucesso": true,
  "mensagem": "Log criado com sucesso"
}

10. Fluxo recomendado de utilização

Fluxo básico:

1. Abrir InstronBridgeSelfHost.exe
2. GET /health
3. GET /state
4. POST /create-sample
5. POST /start-test
6. GET /results/formatted?tableNumber=1
7. POST /save-sample
8. POST /close-sample

Para testes sem movimentar a máquina:

1. Abrir InstronBridgeSelfHost.exe
2. Abrir manualmente no Bluehill uma amostra já existente com resultados
3. GET /results/formatted?tableNumber=1

11. Como consumir a API em PHP

A aplicação PHP pode consumir a API usando cURL.

Se o PHP estiver na mesma máquina da Instron:

$baseUrl = "http://localhost:9000/api/instron";

Se o PHP estiver noutra máquina da mesma rede:

$baseUrl = "http://IP-DA-MAQUINA-INSTRON:9000/api/instron";

Exemplo:

$baseUrl = "http://172.21.0.194:9000/api/instron";

11.1 Health Check em PHP

<?php

$url = "http://localhost:9000/api/instron/health";

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo "Erro cURL: " . curl_error($ch);
} else {
    $data = json_decode($response, true);

    echo "<pre>";
    print_r($data);
    echo "</pre>";
}

curl_close($ch);

11.2 Connect em PHP

<?php

$url = "http://localhost:9000/api/instron/connect";

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);

$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo "Erro cURL: " . curl_error($ch);
} else {
    echo $response;
}

curl_close($ch);

11.3 Create Sample em PHP

<?php

$url = "http://localhost:9000/api/instron/create-sample";

$body = [
    "methodFilePath" => "C:\\Users\\Public\\Documents\\Instron\\Bluehill Universal\\Templates\\metodo.im_tens"
];

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));

$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo "Erro cURL: " . curl_error($ch);
} else {
    $data = json_decode($response, true);

    echo "<pre>";
    print_r($data);
    echo "</pre>";
}

curl_close($ch);

11.4 Start Test em PHP

<?php

$url = "http://localhost:9000/api/instron/start-test";

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);

$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo "Erro cURL: " . curl_error($ch);
} else {
    echo $response;
}

curl_close($ch);

11.5 Results em PHP

<?php

$tableNumber = 1;

$url = "http://localhost:9000/api/instron/results?tableNumber=" . $tableNumber;

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo "Erro cURL: " . curl_error($ch);
} else {
    $data = json_decode($response, true);

    echo "<pre>";
    print_r($data);
    echo "</pre>";
}

curl_close($ch);

11.6 Measurement em PHP

<?php

$measurementName = urlencode("Load");
$unit = urlencode("Newtons");

$url = "http://localhost:9000/api/instron/measurement?measurementName={$measurementName}&unit={$unit}";

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo "Erro cURL: " . curl_error($ch);
} else {
    $data = json_decode($response, true);

    echo "<pre>";
    print_r($data);
    echo "</pre>";
}

curl_close($ch);

12. Classe PHP reutilizável

<?php

class InstronApiClient
{
    private string $baseUrl;

    public function __construct(string $baseUrl = "http://localhost:9000/api/instron")
    {
        $this->baseUrl = rtrim($baseUrl, "/");
    }

    private function request(string $method, string $endpoint, array $body = null)
    {
        $url = $this->baseUrl . $endpoint;

        $ch = curl_init($url);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        if ($method === "POST") {
            curl_setopt($ch, CURLOPT_POST, true);
        }

        if ($body !== null) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                "Content-Type: application/json"
            ]);

            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
        }

        $response = curl_exec($ch);

        if (curl_errno($ch)) {
            throw new Exception(curl_error($ch));
        }

        curl_close($ch);

        return json_decode($response, true);
    }

    public function health()
    {
        return $this->request("GET", "/health");
    }

    public function connect()
    {
        return $this->request("POST", "/connect");
    }

    public function state()
    {
        return $this->request("GET", "/state");
    }

    public function createSample(string $methodFilePath)
    {
        return $this->request("POST", "/create-sample", [
            "methodFilePath" => $methodFilePath
        ]);
    }

    public function startTest()
    {
        return $this->request("POST", "/start-test");
    }

    public function stopTest()
    {
        return $this->request("POST", "/stop-test");
    }

    public function results(int $tableNumber = 1)
    {
        return $this->request("GET", "/results?tableNumber=" . $tableNumber);
    }

    public function saveSample(string $filePath)
    {
        return $this->request("POST", "/save-sample", [
            "filePath" => $filePath
        ]);
    }

    public function closeSample()
    {
        return $this->request("POST", "/close-sample");
    }

    public function measurement(string $measurementName, string $unit)
    {
        return $this->request(
            "GET",
            "/measurement?measurementName=" . urlencode($measurementName) . "&unit=" . urlencode($unit)
        );
    }

    public function disconnect()
    {
        return $this->request("POST", "/disconnect");
    }
}

12.1 Exemplo de uso da classe PHP

<?php

require_once "InstronApiClient.php";

$instron = new InstronApiClient();

try {
    $health = $instron->health();
    print_r($health);

    $connect = $instron->connect();
    print_r($connect);

    $state = $instron->state();
    print_r($state);

} catch (Exception $e) {
    echo "Erro: " . $e->getMessage();
}

13. Cuidados de segurança

Esta API controla ou pode controlar uma máquina física. Portanto:

Não expor esta API diretamente à internet
Executar apenas em rede local ou ambiente controlado
Restringir a porta 9000 na firewall
Permitir apenas máquinas autorizadas
Adicionar autenticação em versões futuras
Manter operador presente durante testes reais
Usar start-test apenas com segurança confirmada

14. Problemas conhecidos e soluções

14.1 /results retorna data null

Possíveis causas:

Amostra não está aberta
Tabela de resultados vazia
Teste ainda não foi executado
Resultados ainda não foram calculados
Número da tabela incorreto

Solução:

Abrir uma amostra com resultados ou executar um teste real antes de consultar /results.

14.2 Erro de arquitetura da Bluehill.API.dll

Erro típico:

An attempt was made to load a program with an incorrect format.

Solução:

Compilar o projeto em x86.

14.3 API não conecta ao Bluehill

Verificar:

Bluehill Universal instalado
Bluehill.API.dll junto ao .exe
Caminho do Bluehill.exe correto
Executar como administrador
Fechar processos antigos do Bluehill

14.4 Porta 9000 não abre

Verificar:

Se o .exe está aberto
Se a firewall permite a porta 9000
Se outro processo já está usando a porta

15. Observação final

Este projeto foi estruturado como SelfHost porque o IIS não manteve corretamente a conexão persistente com o Bluehill entre requests.

Com o SelfHost, a conexão permanece viva enquanto o .exe estiver aberto, tornando a solução mais adequada para integração com software industrial baseado em WCF/Named Pipes.

About

API local desenvolvida em C#/.NET Framework para fazer a ponte entre uma aplicação externa e o software Bluehill Universal da Instron. A aplicação roda como um .exe SelfHost, sem depender do IIS, mantendo a conexão com o Bluehill ativa enquanto o programa estiver aberto.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages