14

Long story short I am trying to write an application that can check cpu temperatures. Using the libsensors(3) man pages I've been able to at least get the libsensors_version number. As of now, here is my code:

#include <sensors/sensors.h>
#include "SensorData.h"
#include <string>
#include <sstream>


using namespace std;

SensorData::SensorData()
{
   sensors_init(NULL);
}

SensorData::~SensorData()
{
    sensors_cleanup();
}

string SensorData::GetVersion()
{
    ostringstream Converter;
    Converter<<"Version: "<<libsensors_version;
    return Converter.str();
}

void SensorData::FetchTemp()
{
    //sensors_get_value()
}

With the man pages I know that sensors_get_value expects

const sensors_chip_name *name
int subfeat_nr
double *value 

to be passed to it. The problem is I have no idea what those are exactly. Just about every function in the documentation has this problem. They all expect vague things I don't know how to supply.

So here is the bulk of the question: Does anyone have any working examples of this library I could look at? Or at the very least does anyone know how to give these functions the values they need?

EDIT:

Since no one seems to know much about this library, does anyone know of a different way to get temperatures?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
CountMurphy
  • 1,086
  • 2
  • 18
  • 39
  • Far easier than using undocumented, obscure, poorly-written, user-unfriendly libraries is using the (equally obscure, slightly better documented) kernel interfaces directly... In this case, [sysfs](https://kernel.org/doc/Documentation/hwmon/sysfs-interface). On my platform, you can find temperatures at `/sys/class/hwmon/hwmon0` or `/sys/bus/platform/devices/coretemp.0/hwmon/hwmon0`. – étale-cohomology Jul 29 '20 at 10:59

3 Answers3

20

You can find out how to use the API by browsing the source code. The code for the sensors program isn't too complex to follow.

To get you started, here's a quick function that:

  • enumerates all the chips
  • enumerates all their features
  • prints the values of their readable subfeatures

You can just add it to your existing skeleton class as-is.

(This code is for demo purposes only, not tested thoroughly at all.)

void SensorData::FetchTemp()
{
    sensors_chip_name const * cn;
    int c = 0;
    while ((cn = sensors_get_detected_chips(0, &c)) != 0) {
        std::cout << "Chip: " << cn->prefix << "/" << cn->path << std::endl;

        sensors_feature const *feat;
        int f = 0;

        while ((feat = sensors_get_features(cn, &f)) != 0) {
            std::cout << f << ": " << feat->name << std::endl;

            sensors_subfeature const *subf;
            int s = 0;

            while ((subf = sensors_get_all_subfeatures(cn, feat, &s)) != 0) {
                std::cout << f << ":" << s << ":" << subf->name
                          << "/" << subf->number << " = ";
                double val;
                if (subf->flags & SENSORS_MODE_R) {
                    int rc = sensors_get_value(cn, subf->number, &val);
                    if (rc < 0) {
                        std::cout << "err: " << rc;
                    } else {
                        std::cout << val;
                    }
                }
                std::cout << std::endl;
            }
        }
    }
}
Mat
  • 202,337
  • 40
  • 393
  • 406
  • Actually seeing code helps a lot. Thank you. I'll have to give this a go later tonight. – CountMurphy Dec 19 '11 at 17:50
  • 2
    Note: it is required to call `sensors_init()` before otherwise the chips list will be empty (don't blindly copy/paste this snippet like I did :) ). – Delgan Jul 21 '21 at 07:54
2

The Gnome panel Sensors applet works with libsensors (and other backends); the full sources are available from Sourceforge, here: http://sensors-applet.sourceforge.net/index.php?content=source

… in particular, the libsensors plug-in looks fairly legible… I believe this should be a usable gitweb link straight to that code: http://sensors-applet.git.sourceforge.net/git/gitweb.cgi?p=sensors-applet/sensors-applet;a=blob;f=plugins/libsensors/libsensors-plugin.c;h=960c19f4c36902dee4e20b690f2e3dfe6c715279;hb=HEAD

BRPocock
  • 13,638
  • 3
  • 31
  • 50
1

Your code should looks like this:

/* Read /etc/sensors.d to get the names or use code in above post */
std::string chip_name = "CHIP_NAME-*";

/* Here you get the path to the chip you want to read */
int rc;
sensors_chip_name name;

rc = sensors_parse_chip_name(chip_name.c_str(), &name);
/* Check rc != 0 */

/* Here you get the internal structure */
int nr = 0; //Here I silently assume you have only one chip to read
const sensors_chip_name* p_chip;
p_chip = sensors_get_detected_chips(&name, &nr);
/* Check p_chip != 0 */


/* Now you read the value - this you can repeat in some for/while cycle */
double val;
/* Replace the "1" with the feature you want to read */
rc = sensors_get_value(p_chip, 1, &val);

std::cout << "Now I can use sensors library " << val << std::endl;

Hope it helps despite the fact it is not copy/paste solution.

You can obtain the const sensors_chip_name* p_chip; from the code above post as well.

I believe the problem is in fact the const sensors_chip_name MUST be returned and filled by sensors library.

Ondrej H
  • 11
  • 2