Has anyone been able to use libsensors properly?
Asked Answered
G

3

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?

Galenical answered 19/12, 2011 at 2:32 Comment(1)
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. On my platform, you can find temperatures at /sys/class/hwmon/hwmon0 or /sys/bus/platform/devices/coretemp.0/hwmon/hwmon0.Galliwasp
B
22

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;
            }
        }
    }
}
Ballot answered 19/12, 2011 at 17:40 Comment(2)
Actually seeing code helps a lot. Thank you. I'll have to give this a go later tonight.Galenical
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 :) ).Chard
L
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

Loyceloyd answered 19/12, 2011 at 17:55 Comment(0)
O
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.

Orangeade answered 19/11, 2021 at 9:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.