Da wir nun in der Firma den PRTG Network Monitor einsetzen und auch
die Server Raumtemperatur und Luftfeuchtigkeit damit überwachen
und festhalten wollen, habe ich mich mal hingesetzt und einen
kleinen Arduino PRTG Raumsensor gebaut.
Er wird über Netzwerk angesprochen und gibt dann ein JSON-Objekt
wieder der dann im PRTG mit einen HTTP XML/REST Sensor
verarbeitet werden kann.
Die Stückliste:
- Arduino Uno (Clone)
- Ethernet Shield
- DS18S20 (Temperaturfühler)
- DHT11 (Feuchtigkeitssensor)
Code:
#include <EEPROM.h> #include <DHT.h> #include <OneWire.h> #include <DallasTemperature.h> #include <SPI.h> #include <Ethernet.h> #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() > 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 == '?' && parm == "") { gflag = true; } if (c == '\n' && 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(&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 << 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("<html><head><title>Arduino PRTG Raumsensor</title></head>")); client.println(F("<body bgcolor='#BDBDBD'><table width='100%'>")); client.println(F("<tr><td colspan='2' align='center'><h1>Arduino PRTG Raumsensor</h1></td></tr>")); client.println(F("<tr><td align='center'><table bgcolor='#FFFFFF' border = '1'>")); client.print(F("<tr><td colspan='2' align='center'><b>JSON API</b></td></tr>")); client.print(F("<tr><td>http://")); client.print(Ethernet.localIP()); client.println(F("/?sensor=all</td>")); client.println(F("<td>Fragt alle Sensoren ab.</td></tr>")); client.print(F("<tr><td>http://")); client.print(Ethernet.localIP()); client.println(F("/?sensor=temp</td>")); client.println(F("<td>Fragt den Temperatursensor ab.</td></tr>")); client.print(F("<tr><td>http://")); client.print(Ethernet.localIP()); client.println(F("/?sensor=hum</td>")); client.println(F("<td>Fragt den Luftfeuchtesensor ab.</td></tr>")); client.print(F("<tr><td>http://")); client.print(Ethernet.localIP()); client.println(F("/?sensor=volt</td>")); client.println(F("<td>Fragt den Spannungsversorgungs Sensor ab.</td></tr>")); client.println(F("</table></td></tr>")); client.println(F("<tr><td align='center'><table bgcolor='#FFFFFF' border = '1'>")); client.println(F("<tr><td colspan='2' align='center'><b>Serial Config</b></td></tr> <br />")); client.print(F("<tr><td>setip=")); client.print(Ethernet.localIP()); client.println(F("</td><td>Setzt eine neue IP-Adresse.</td></tr></body></html>")); } 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(&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(); } }
2 Kommentare
Christoph · 7. Dezember 2016 um 23:54
Hallo, die Idee gefällt mir ganz gut! Super Arbeit – gibt es auch eine Möglichkeit einen Digitalen PIN ab zu fragen ? – eventuell für einen Rauchsensor bzw. Wassersensor ?
Shojo · 7. Dezember 2016 um 23:58
Klar alles was sich an einen Arduino betreiben lässt ;o)