[HOW TO] PRTG – Temperatur Sensor – Arduino

Da wir in der Firma PRTG als Monitoring System verwenden und diese auch privat verwende (bis 50 Sensoren Gratis), hätte ich gerne einen Temperatursensor mit eingebunden, um verschiedene Sachen zu überwachen. zB: Serverschrank Temperatur, etc.

Natürlich könnte so auch die Aussentemperatur etc. überwacht werden.

Funktion: 

Der Arduino wird über das Ethernet Shield angesprochen, dass ein JSON-Objekt an den PRTG Server übermittelt. (HTTP XML/REST Sensor)

Was wird benötigt:

  • Arduino Uno (R3)
  • Gehäuse
  • Ethernet Shield
  • Dallas DS18S20 (Temperaturfühler)
  • 4,7 K Widerstand für Datenleitung
  • DHT11 inkl. 10K Widerstand (Feuchtigkeitssensor)

Arduino libs:

  • #include <EEPROM.h> — Aus der Bibliothek
  • #include <DHT.h> — Aus der Bibliothek
  • #include <OneWire.h> — Aus der Bibliothek
  • #include <DallasTemperature.h> — Aus der Bibliothek
  • #include <SPI.h> — Aus der Bibliothek
  • #include <Ethernet.h> — Aus der Bibliothek
  • #include „EEPROMAnything.h“ — zum Download bzw. selber Anlegen

Schaltplan:

  • DS18S20 an PIN 7
  • DHT11 an PIN 8

prtg-arduino_steckplatine

Arduino Code:

#include &lt;EEPROM.h&gt;
#include &lt;DHT.h&gt;
#include &lt;OneWire.h&gt;
#include &lt;DallasTemperature.h&gt;
#include &lt;SPI.h&gt;
#include &lt;Ethernet.h&gt;
#include "EEPROMAnything.h"

boolean gflag = false;
String parm;
const byte OW_MessurePin = 7;

IPAddress defaultIP(192, 168, 0, 86);
byte mac[] = { 0XDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

struct config_t
{
byte ip0;
byte ip1;
byte ip2;
byte ip3;
boolean isConfig;
}
Conf;

EthernetServer server(80);

void setup()
{
EEPROM_readAnything(0, Conf);
IPAddress ip(Conf.ip0, Conf.ip1, Conf.ip2, Conf.ip3);
Serial.println(Conf.isConfig);
if (!Conf.isConfig)
{
Ethernet.begin(mac, defaultIP);
}
else
{
Ethernet.begin(mac, ip);
}

Serial.begin(9600);
server.begin();
Serial.print(F("Arduino PRTG Raumsensor gestartet (IP:"));
Serial.print(Ethernet.localIP());
Serial.println(F(")"));
}

void loop()
{
EthernetClient client = server.available();
if (Serial.available() &gt; 0)
{
String inputLine = Serial.readStringUntil('\n');
SerialConfig(inputLine);
}

if (client)
{
boolean currentLineIsBlank = true;

while (client.connected())
{
if (client.available())
{
char c = client.read();

// serch parameter from "HTTP GET"
if (gflag) {
if (c != ' ') {
parm += c;
}
else {
gflag = false;
}
}
if (c == '?' &amp;&amp; parm == "") {
gflag = true;
}

if (c == '\n' &amp;&amp; currentLineIsBlank)
{
if (parm == "")
{
SendInfoPage(client);
}
else
{
parm.toLowerCase();
String result = "";

if (parm.startsWith("sensor"))
{
if (parm.startsWith("all", 7))
{
result = GetAllSens();
}
else if (parm.startsWith("hum", 7))
{
result = GetHumSens();
}
else if (parm.startsWith("temp", 7))
{
result = GetTempSens();
}
else if (parm.startsWith("volt", 7))
{
result = GetVoltSens();
}
}

if (result != "")
{
SendDataJson(client, result);
}
else
{
SendInfoPage(client);
}
}
parm = "";
break;
}

if (c == '\n')
{
currentLineIsBlank = true;
}
else if (c != '\r')
{
currentLineIsBlank = false;
}
}
}
delay(1);

client.stop();
}
}

String GetAllSens()
{
char buffer[7];
String result = "[{\"temperature\":";
result += (dtostrf(Temp(), 3, 2, buffer));
result += ", \"humidity\":";
result += (dtostrf(Humidity(), 3, 0, buffer));
result += ", \"voltage\":";
result += (dtostrf(readVcc(), 3, 2, buffer));
result += "}]";

return result;
}

String GetTempSens()
{
char buffer[7];
String result = "[{\"temperature\":";
result += (dtostrf(Temp(), 3, 2, buffer));
result += "}]";

return result;
}

String GetHumSens()
{
char buffer[4];
String result = "[{\"humidity\":";
result += (dtostrf(Humidity(), 3, 0, buffer));
result += "}]";

return result;
}

String GetVoltSens()
{
char buffer[6];
String result = "[{\"voltage\":";
result += (dtostrf(readVcc(), 2, 2, buffer));
result += "}]";

return result;
}

float Temp()
{
delay(20);
OneWire oneWire(OW_MessurePin);
DallasTemperature sensors(&amp;oneWire);
sensors.begin();
sensors.setResolution(12);
sensors.requestTemperatures();
float iTemperatur = sensors.getTempCByIndex(0);
while (iTemperatur == 12768 || iTemperatur == 8500)
{
Serial.println(F("Fehlmessung, wiederhole die Messung!"));
iTemperatur = sensors.getTempCByIndex(0);
}

return iTemperatur;
}

int Humidity()
{
DHT dht(8, DHT11);
dht.begin();
return dht.readHumidity();
}

float readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif

delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA, ADSC)); // measuring

uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both

float result = (high &lt;&lt; 8) | low;

result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
return result / 1000; // Vcc in millivolts
}

void SendInfoPage(EthernetClient client)
{
client.println(F("HTTP/1.1 200 OK"));
client.println(F("Content-Type: text/html"));
client.println();
client.println(F("&lt;html&gt;&lt;head&gt;&lt;title&gt;Arduino PRTG Raumsensor&lt;/title&gt;&lt;/head&gt;"));
client.println(F("&lt;body bgcolor='#BDBDBD'&gt;&lt;table width='100%'&gt;"));
client.println(F("&lt;tr&gt;&lt;td colspan='2' align='center'&gt;&lt;h1&gt;Arduino PRTG Raumsensor&lt;/h1&gt;&lt;/td&gt;&lt;/tr&gt;"));
client.println(F("&lt;tr&gt;&lt;td align='center'&gt;&lt;table bgcolor='#FFFFFF' border = '1'&gt;"));
client.print(F("&lt;tr&gt;&lt;td colspan='2' align='center'&gt;&lt;b&gt;JSON API&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;"));

client.print(F("&lt;tr&gt;&lt;td&gt;http://"));
client.print(Ethernet.localIP());
client.println(F("/?sensor=all&lt;/td&gt;"));
client.println(F("&lt;td&gt;Fragt alle Sensoren ab.&lt;/td&gt;&lt;/tr&gt;"));

client.print(F("&lt;tr&gt;&lt;td&gt;http://"));
client.print(Ethernet.localIP());
client.println(F("/?sensor=temp&lt;/td&gt;"));
client.println(F("&lt;td&gt;Fragt den Temperatursensor ab.&lt;/td&gt;&lt;/tr&gt;"));

client.print(F("&lt;tr&gt;&lt;td&gt;http://"));
client.print(Ethernet.localIP());
client.println(F("/?sensor=hum&lt;/td&gt;"));
client.println(F("&lt;td&gt;Fragt den Luftfeuchtesensor ab.&lt;/td&gt;&lt;/tr&gt;"));

client.print(F("&lt;tr&gt;&lt;td&gt;http://"));
client.print(Ethernet.localIP());
client.println(F("/?sensor=volt&lt;/td&gt;"));
client.println(F("&lt;td&gt;Fragt den Spannungsversorgungs Sensor ab.&lt;/td&gt;&lt;/tr&gt;"));

client.println(F("&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;"));
client.println(F("&lt;tr&gt;&lt;td align='center'&gt;&lt;table bgcolor='#FFFFFF' border = '1'&gt;"));
client.println(F("&lt;tr&gt;&lt;td colspan='2' align='center'&gt;&lt;b&gt;Serial Configuration&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt; &lt;br /&gt;"));
client.print(F("&lt;tr&gt;&lt;td&gt;setip="));
client.print(Ethernet.localIP());
client.println(F("&lt;/td&gt;&lt;td&gt;Setzt eine neue IP-Adresse.&lt;/td&gt;&lt;/tr&gt;&lt;/body&gt;&lt;/html&gt;"));
}

void SendDataJson(EthernetClient client, String result)
{
Serial.println(result);
client.println(F("HTTP/1.1 200 OK"));
client.println(F("Content-Type: application/json"));
client.print(F("Content-Length: "));
client.println(result.length());
client.println(F("Connection: close"));
client.println();
client.println(result);
}

void SerialConfig(String inputLine)
{
inputLine.toLowerCase();

if (inputLine.startsWith("setip="))
{
inputLine.replace("setip=", "");
String ArrayKey[4];
char *tmp;
int i = 0;
tmp = strtok(&amp;inputLine[0u], ".");
while (tmp) {
ArrayKey[i++] = tmp;
tmp = strtok(NULL, ".");

}

Conf.ip0 = atoi(ArrayKey[0].c_str());
Conf.ip1 = atoi(ArrayKey[1].c_str());
Conf.ip2 = atoi(ArrayKey[2].c_str());
Conf.ip3 = atoi(ArrayKey[3].c_str());

Conf.isConfig = TRUE;

EEPROM_writeAnything(0, Conf);
Serial.println(F("Neue IP-Adresse gespeichert, starte neu!"));
delay(500);
void(*pseudoReset)(void) = 0;
pseudoReset();
}
}

PRTG Einbindung

Als letzter Schritt muss der Sensor in PRTG eingebunden werden. Pro Wert den wir Überwachen wollen muss ein Sensor verwendet werden.

  • HTTP XML/REST Wert

2016-12-04-03_13_16

Schritt zwei:

  • URL: http://IP/?sensor=Sensor
  • XML Kontro – ehumidity, temperature oder voltage
  • Für Luftfeuchtigkeit: http://IP/?sensor=hum
  • XML Konten: humidity
  • Für Tempertatur: http://IP/?sensor=temp
  • XML Konten: temperature
  • Für Volt: http://IP/?sensor=volt
  • XML Konten: voltage

2016-12-04-03_14_00

2016-12-04-02_29_17

 

Viel Spaß beim nachbauen!

Quellen: https://www.bastelbunker.de; http://playground.arduino.cc/Learning/OneWire-DE; http://playground.arduino.cc/Main/DHTLib; https://www.paessler.com/manuals/prtg/http_xmlrest_value_sensor