Monitoring a Terrarium With PRTG

 By Shaun Behrens
Oct 18, 2019 • 9 minute read

This is Merlin, a 6-year-old corn snake. He lives in a terrarium in a home in Switzerland, where he's taken care of by Patrick and his wife. Generally, even though corn snakes are relatively easy to care for (making them ideal pet snakes), Patrick—being an electrical engineer—had a compulsion to do something geeky with the terrarium. He eventually decided on measuring the temperature and humidity in the terrarium remotely. Here's the story of how he came up with a solution involving PRTG Network Monitor.

Environmental monitoring

There are many consumer products that let you measure temperature and humidity, like OpenHAB or Domoticz, but none of these options really fulfilled Patrick's needs. Whether it was because of a Web interface that wasn't intuitive, or complicated ways to connect sensors, nothing appealed to him.

Merlin2After some searching, he eventually found a WLAN switch module with connections for a temperature and humidity sensor (a Sonoff TH10). He then flashed it with Tasmota software so that he could integrate it into an MQTT-based sensor network. He used this solution with Domoticz, but was only moderately satisfied with it.

Then, one evening, it occurred to Patrick that maybe he could use PRTG to monitor the temperature and humidity of the terrarium, and so he sat down at his computer and got to work.

PRTG Network Terrarium Monitor

The Tasmota firmware that Patrick installed on the Sonoff TH10 allows him to query the current temperature and humidity values using an HTTP command. Patrick wrote a short JAVA program that queries these values, and prepares an XML output file that can be understood by PRTG. 

In PRTG, Patrick uses the EXE/Script Advanced sensor to call the JAVA program every minute using a batch file. As an input argument, the batch file provides an IP address to the JAVA program (in this case, the IP address of the Sonoff TH10). This also means that the solution can be used for other devices, too, by changing the IP address. 

The EXE/Script Advanced sensor then uses the XML file produced by the JAVA program to display the measured data in two channels: Temperature and Humidity. 

Here's an example of the graph that the whole process generates: 

ScreenshotClimateGraph2d

Patrick can also set the sensor to provide him with "Warning" and "Error" notifications if the temperature and humidity values go too high or too low, and he can react to this data. So not only is Patrick utilizing PRTG to keep an eye on his home network, but he is also ensuring that Merlin feels comfortable in his terrarium. Everything from one app! 

Sample JAVA code

Here's a sample of Patrick's JAVA program that is called by the EXE/Script Advanced sensor.

package tasmotareader;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* @author Patrick
* @version 1.1
*/

public class TasmotaReader
{
/**
* @param args The Command Line Arguments
*/
public static void main(String[] args)
{
// Start Building XML Response
System.out.println("<prtg>");

// Check Correct Number of Arguments Received
if (args.length == 1)
{
// Number of Command Line Arguments Correct

// Initialize IO
BufferedReader in = null;

// Do Or Do Not, There Is No Try...
try
{
// Get IP from first Command Line Argument
String IP = args[0];

// Build URL from IP
URL tasmotaURL = new URL("http://" + IP + "/cm?cmnd=status%2010");

// Create IO to Read Answer
in = new BufferedReader(
new InputStreamReader(tasmotaURL.openStream()));

// Variable for Line-by-Line Reading of HTTP Response
String inputLine;

// Read HTTP Response until Values found or Response Ends
while ((inputLine = in.readLine()) != null)
{
// Search for Keyword
if (inputLine.startsWith("STATUS10"))
{
// Keyword found, Split String to Isolate Values
String[] splitStrings = inputLine.split("AM2301");
splitStrings = splitStrings[1].split(":");

// Split some more...
String sTemp = splitStrings[2].substring(0,4);
String sHumidity = splitStrings[3].substring(0,4);

// Continue building XML Response
// Add Temperature Channel
System.out.println("<result>");
System.out.println("<channel>Temperature</channel>\r\n"
+ "<unit>°C</unit>\r\n<float>1</float>\r\n"
+ "<value>" + sTemp + "</value>");
System.out.println("</result>");
// Add Humidity Channel
System.out.println("<result>");
System.out.println("<channel>Humidity</channel>\r\n"
+ "<unit>%rH</unit>\r\n<float>1</float>\r\n"
+ "<value>" + sHumidity + "</value>");
System.out.println("</result>");

// Leave While-Loop
break;
}
}
// Close IO
in.close();

// Finalize XML Response
System.out.println("</prtg>");

// Go Home Happy
System.exit(0);
}
// URL Malformed Exception Handling
catch (MalformedURLException ex)
{
// Write Error To XML Response
System.out.println("<error>2</error>\r\n<text>Invalid URL - "
+ ex.toString() + "</text>");
System.out.println("</prtg>");
// Go Home Sad
System.exit(1);
}
// General IO Exception Handling
catch (IOException ex)
{
// Write Error To XML Response
System.out.println("<error>2</error>\r\n<text>I/O Exception - "
+ ex.toString() + "</text>");
System.out.println("</prtg>");
// Go Home Sad
System.exit(1);
}
finally
{
// Close IO Gracefully
if (in != null)
{
try
{
in.close();
}
catch (IOException ex)
{
// Exception While Trying to Gracefully Close IO
// Shall be Ignored Here
// Go Home Sad
System.exit(1);
}
}
}
}
// Number of Command Line Arguments Incorrect
else
{
// Write Error To XML Response
System.out.println("<error>2</error>\r\n<text>Invalid Arguments ("
+ args.length + " args)</text>");
System.out.println("</prtg>");
// Go Home Sad
System.exit(1);
}
}
}

 

Send us your use cases!

This isn't the first time PRTG helped keep an animal comfortable: way back in 2017, we wrote about Flash the turtle who had the temperature of its tank monitored.

Do you have cool use cases of PRTG? Then let us know in the comments below and you might be featured on our blog!