Sonntag, 29. Dezember 2013

HTTP-POST zu ASP.net Web API mit Arduino

Web APIs (auch REST-Services genannt) sind in der heutigen Zeit nicht mehr wegzudenken. (siehe auch wie Web APIs helfen Wertschöpfungsketten zu verändern). Ein Arduino Uno ist – mit Hilfe vom geeigneten Shield – in der Lage mit einem Web API zu kommunizieren. Für mein aktuelles Projekt war es von Nöten, dass das Arduino an einen ASP.net Web API 2 REST-Service einen POST-Request schicken kann. Anbei eine Anleitung, welche anderen Personen mit dieser Herausforderung helfen kann.

Benötigte Bauteile

Folgende Bauteile wurden für den Arduino-Teil benötigt:

1x Arduino Uno:

Bild eines Arduino Uno

1x Arduino Ethernet Shield:

Bild eines Arduino Ethernet Shield

Kombiniert sieht das dann so aus:

Bild eines Arduino Uno mit Ethernet Shield

Arduino-Sketch

Der Arduino-Sketch sieht wie folgt aus und macht in groben Zügen folgendes.

  1. IP-Adresse vom DHCP-Server beziehen. Falls DHCP-Server nicht funktioniert, verwendet Arduino die IP-Adresse 192.168.1.177
  2. Prüfen ob der Server wo der REST-Service läuft erreichbar ist (in meinem Fall 192.168.1.40:8090)
  3. Alle 30 Sekunden einen POST-Request auf http://192.168.1.40:8090/api/mail mit der Message "bla" senden
#include <Ethernet.h>
#include <SPI.h>
 
 
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x42, 0xF2 }; // Bei den neueren Shields ist die MAC-Adresse mit einem Sticker raufgedruckt  
byte ip[] = { 192, 168, 1, 177 }; // Fallback IP-Adresse   
 
int baudRate = 9600;
 
byte serverIP[] = { 192, 168, 1, 40 }; //WICHTIG: Eine IP-Adresse muss als byte-Array geführt werden!! Hostnamen als char-Array
int serverPort= 8090;
 
EthernetClient client;
 
void setup()
{
  Serial.begin(baudRate);
  
  delay(5000); // Delay welcher ermöglicht nach dem Starten noch den Serial-Monitor zu starten
  
  // Versuche eine Ethernet-Verbindung anhand DHCP aufzubauen
  if(Ethernet.begin(mac) == 0) {
    Serial.println("Verbindung via DHCP konnte nicht hergestellt werden. Vergebe fixe IP-Adresse");
    Ethernet.begin(mac,ip); // Wird kein DHCP gefunden, so verwende die statische IP 192.168.1.177
  }
  delay(4000); //Kurz warten um EthernetShield-Konfiguration einzuspielen
  VerbindungTesten();
}
 
void loop()
{
  delay(5000);
  Serial.println("HTTP-POST an REST-Service");
  MachePostZuRestService();
  Serial.println("Ausführung abgeschlossen");
  delay(30000);
}
 
void MachePostZuRestService()
{
  if(client.connect(serverIP,serverPort))
  {
    Serial.println("Mit dem Server verbunden.");
    Serial.println("Mache HTTP-Post");
    client.println("POST /api/mail HTTP/1.1");
    client.println("Host: 192.168.1.40");
    client.println("Content-Type: application/json"); // Inhalt als JSON versenden, damit ASP.net MVC WebAPI korrekt damit umgehen kann
    client.println("Content-Length: 5"); // Die Content-Länge muss mit "bla" übereinstimmen
    client.println("Connection: Close"); // Wir erwarten, dass der REST-Service kein Result zurückliefert (HTTP 204: No Content)
    client.println();
    client.println(""bla"");
    client.stop();
  }
  else
  {
    Serial.println("Konnte mich nicht mit dem Server verbinden!");
  }
}
 
void VerbindungTesten()
{
  Serial.println("Meine IP Adresse: ");
  Serial.println(Ethernet.localIP());
  delay(2000);
  Serial.println("Teste Verbindungsaufbau zu Server");
  if (client.connect(serverIP, serverPort)) {
    Serial.println("Mit dem Server verbunden. Schliesse Verbindung");
    client.stop();
    Serial.println("Verbindung geschlossen");
  } 
  else 
  {
    Serial.println("FEHLER: Konnte mich nicht mit dem Server verbinden!");
  } 
}

ASP.net Web API 2 Code

Der ASP.net Web API 2 Service ist hier nur Dummy-Haft dargestellt. Erreichbar ist die entsprechende Service-Methode mittels einem POST-Request unter http://192.168.1.40:8090/api/mail

using System.Web.Http;
 
namespace RestService.Controllers
{
    public class MailController : ApiController
    {
        public void Post([FromBody]string value)
        {
            // Mach hier etwas mit der Information
        }
    }
}
Autor

Reto Gurtner