Temperature monitoring always plays an important role in IT. There are various very expensive solutions for this purpose. In this article, I will show you an inexpensive alternative.

Normally we use a Raspberry Pi for such things, but here is a solution that also works well with existing Windows computers.

needed Hardware

With the help of a small pcb that is connected to the Windows computer via USB, we can read out up to 8 DS18B20 temperature sensors.

https://www.diamex.de/dxshop/USB-Temperatur-Sensor-Tester-fuer-DS18B20-Rev-C

The Sensor can also be putted in the Basket @Diamex.

How do I get the measured values into Icinga?

From this point on, things get really ugly: 😐

  1. the supplied software seems to be quite old
  2. the command line tool is not really helpful as it simply spits out the current values over and over again. No arguments
  3. i've tried some batch attempts without success (start program, output to file, stop program after 3 seconds, cat the file)

But hey there is the source ! it is in the CMDLINE Folder of the .zip

a quick look at the Makefile tells me it is probably better to compile the whole thing under Windows. (Linux does not know the appropriate header files and it is difficult to find them...)

RWill_2024-07-16%2017-45-55

So let's go ahead and start by creating a development environment for the aforementioned CLItool (main.c).

The MakeFile shows us that MinGW can be used:

25 CC = gcc.exe #i586-mingwmsvc-gcc

Setup MinGW Environment

  1. Look for mingw-get-setup.exe for downloading. Download and launch the installer. Accept the terms and move on.
  2. You'll now see that the installer is connecting to the internet and downloading a lot of tiny and small files. Wait till it ends.
  3. Right when it ends (which won't take long), you'll be presented a window with title MinGW Installation Manager. You should be in the Basic Setup tab by default when it launches. If not, click on Basic Setup
  4. Out of numerous check boxes presented to you on the right side, tick mingw32-gcc-g++-bin. If you are prompted with a menu, click on Mark for install.
  5. Next select MSYS Base System in the Left pane and check msys-make-bin
  6. Then on the top left corner click on Installation > Apply Changes. And wait while it downloads a billion files and installs them

RWill_2024-07-16%2017-59-08

You can put the Installation in background and proceed or wait for the next steps:

  1. Now you gotta edit your Environment Variables as well, so that gcc works in cmd no matter the file location.
  2. For that go to Windows Explorer -> Right click on this PC -> Properties -> Advanced system settings -> Environment Variables or you could just search for Environment Variables in Windows Search...
  3. At the bottom System Variables panel, look for a Variable named Path and double click on it. Some Systems show a good UI for adding a New Path easily (by clicking New), else you just need to add ; at the end and add the following paths
C:\MinGW\bin
C:\Mingw\msys\1.0\bin

on my windows 10 it looks like:

RWill_2024-07-16%2018-05-56

  1. Click on OK, and OK and close the other windows. Open a Command Prompt and try typing gcc --version and press Enter.

If you got something like

RWill_2024-07-16%2018-09-25

gcc is fine. Please test also that a make should also respond with ...no targets specified.

build the check_command

I have added lines 50-55 to the main.c file. Depending on the temperature, this ends with exit(1) or exit(2). Icinga uses the return code to output a warning or critical error accordingly And sorry my c++ is very rusty. Maybe someone can add the thresholds temps as cargs (Warning 30℃ / 35℃ critical)?

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#if defined(OS_LINUX) || defined(OS_MACOSX)
  #include <sys/ioctl.h>
  #include <termios.h>
#elif defined(OS_WINDOWS)
  #include <conio.h>
#endif

#include "hid.h"
//*----------------------------------------------------------------------------
static char getkey(void);
//*----------------------------------------------------------------------------
int main()
{
    int i, r, num, temp;
    char c, buf[64], *pwr;

    r = rawhid_open(1, 0x16C0, 0x0480, 0xFFAB, 0x0200);
    if (r <= 0) {
        fprintf(stdout, "No Temp-Sensor found\n");
        return -1;
    }
    fprintf(stdout, "Raffis Tempreader\n");
    //fprintf(stdout, "Found Temp-Sensor\n");

    while (1) {
        //....................................
        // check if any Raw HID packet has arrived
        //....................................
        num = rawhid_recv(0, buf, 64, 220);
        if (num < 0) {
            fprintf(stdout, "\nError Reading\n");
            rawhid_close(0);
            return 0;
        }

        if (num == 64) {
         temp = *(short *)&buf[4];
         if(buf[2]) { pwr = "Extern"; }
               else { pwr = "Parasite"; }
         fprintf(stdout, "Sensor #%d of %d: %+.1f""C Power: %-10s ID: ", buf[1], buf[0], temp / 10.0, pwr);

            for (i = 0x08; i < 0x10; i++) {
                fprintf(stdout, "%02X ", (unsigned char)buf[i]);
            }
            fprintf(stdout, "\n");
        if ( temp / 10.0 > 35) {
            exit (2);
        }
        if ( temp / 10.0 > 30) {
            exit(1);
        }
        exit(0);
        }
        //....................................
        // check if any input on stdin
        //....................................
        c = getkey();
        if(c == 0x1B) { return 0; }   // ESC
        if(c >= 32) {
            fprintf(stdout, "\ngot key '%c', sending...\n", c);
            buf[0] = c;
            for (i=1; i<64; i++) {
                buf[i] = 0;
            }
            rawhid_send(0, buf, 64, 100);
        }
    }
}
//*----------------------------------------------------------------------------
#if defined(OS_LINUX) || defined(OS_MACOSX)
// Linux (POSIX) implementation of _kbhit().
// Morgan McGuire, morgan@cs.brown.edu
static int _kbhit() {
    static const int STDIN = 0;
    static int initialized = 0;
    int bytesWaiting;

    if (!initialized) {
        // Use termios to turn off line buffering
        struct termios term;
        tcgetattr(STDIN, &term);
        term.c_lflag &= ~ICANON;
        tcsetattr(STDIN, TCSANOW, &term);
        setbuf(stdin, NULL);
        initialized = 1;
    }
    ioctl(STDIN, FIONREAD, &bytesWaiting);
    return bytesWaiting;
}
static char _getch(void) {
    char c;
    if (fread(&c, 1, 1, stdin) < 1) return 0;
    return c;
}
#endif
//*----------------------------------------------------------------------------
static char getkey(void)
{
    if (_kbhit()) {
        char c = _getch();
        if (c != 0) return c;
    }
    return 0;
}
//*----------------------------------------------------------------------------

After this modification we can compile the main.c

compile the main.c

  1. Start a Command Prompt and navigate to the Folder that contains the files from the .zip (CMDLINE)
  2. run make and hope that it runs through (dont forget to create the .deps folder with mkdir)

RWill_2024-07-16%2018-31-43

Setup Check_Command

The created .exe must be copied to c:\Program Files\ICINGA2\sbin\

After this you can create a Check_Command on the Machine and Done 🙂

RWill_2024-07-16%2017-40-35

Previous Post Next Post