Other sysctl ow_temp in a GTKwindow

I have some Dallas One Wire Temperature Modules that present a sysctl interface that I would like to display in a GTKwindow on a RaspPi2.

Looking around I found this function: sysctlbyname() which seems to fit the bill for dev.ow_temp.
I am finding few examples but this seems the best but is 10 years old:
http://www.cs.unc.edu/~jeffay/dirt/FAQ/sysctl.html
Is this still accurate?

Am I heading in the right direction? Get my function together then use with Glade?

Am I reinventing the wheel or is there a better way?
 
Well good I thought the same way, looked at monitoring tools and then I thought, I also want to do a hostapd-monitor gui and most settings there have sysctl variables too. So learning this most basic control mechanism is probably a good route to start with. I see lots of py-GTK and py-GObject usage but I think a simple C program is where I need to start. Something like get_ow_temp.
Thoughts?

Then insert that c program into a gui. Does that sound right??
What about Glade versus raw GTK+. Should I ditch the IDE early? It seems an easy route to draw windows with nice features.
 
OK thanks to Carpetsmoker old post I got a jumpstart.
http://daemonforums.org/showthread.php?t=2698

My first real C program:
get_temp.c
Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>

int
main()
{
        size_t size;
        int buf;
        size = sizeof buf;

        sysctlbyname("dev.ow_temp.0.temperature", &buf, &size, NULL, 0);
        printf("%d\n", buf);
        return 0;
}

I have it returning a value but it is wrong. Any advice? I am free of compile errors now.

root@rpi2:~ # ./get_temp
295587
root@rpi2:~ #
 
root@rpi2:~ # sysctl -x dev.ow_temp.0.temperature
dev.ow_temp.0.temperature: 0x000482e2
Hex dump of value, So its not that.

root@rpi2:~ # sysctl -t dev.ow_temp.0.temperature
dev.ow_temp.0.temperature: integer
type looks right

root@rpi2:~ # sysctl dev.ow_temp.0.temperature
dev.ow_temp.0.temperature: 22.500C
Here is what it should show.
 
If you look at the source for ow_temp(4) this is how the sysctl is added:
Code:
        SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
            SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
            OID_AUTO, "temperature", CTLFLAG_RD | CTLTYPE_INT,
            &sc->temp, 0, sysctl_handle_int,
            "IK3", "Current Temperature");
"IK3" is a formatting hint for sysctl(8) for how it should print and interpret the value (see SYSCTL_ADD_PROC(9)).

IK3 means it's a temperature in Milli-Kelvin i.e. to print the temperature in degree Celsius you'd need to convert it first. You loose precision this way, but HTH:
Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>

int
main()
{
        size_t size;
        int buf;
        size = sizeof buf;

        sysctlbyname("dev.ow_temp.0.temperature", &buf, &size, NULL, 0);
	buf -= 273150; // 0 Kelvin == -273.15 C
	buf *= 1e-3;

        printf("%d\n", buf);
        return 0;
}
 
Thank You so much for the help.
Code:
int
main ()
{
        size_t size;
        int buf;
        size = sizeof buf;

        sysctlbyname("dev.ow_temp.0.temperature", &buf, &size, NULL, 0);
        buf -=273150; // 0 Kelvin == -273.15 C
        buf *= 1e-3;
        printf("%d\n");
        return 0;
}

"/root/get_temperature.c" 17 lines, 276 characters
Code:
root@rpi2:~ # cc get_temperature.c -o get_temp
get_temperature.c:14:11: warning: more '%' conversions than data arguments
      [-Wformat]
        printf("%d\n");
                ~^
1 warning generated.

root@rpi2:~ # ./get_temp
34638

Still not right? Glad to know where to look though.
 
Yes, those lines do the conversion.

Code:
root@rpi2:~ # cc get_temperature.c -o get_temp
get_temperature.c:14:11: warning: more '%' conversions than data arguments
     [-Wformat]
        printf("%d\n");
                ~^
1 warning generated.

The compiler is telling you that an argument for printf is missing, in fact if you look at tobik example the right statement is:
Code:
       printf("%d\n", buf);
 
printf("%d\n");
You removed buf here. The compiler even cluebats you about it ;)

So with these lines you are doing math on the buffer??
Subtract 273150 and then multiply by 1000?
Yes, but divide by 1000. The conversion in math notation (I used the hex value you gave as the initial value for T):
2017-01-08-175307_392x395_scrot.png
 
Perfect! Well you can tell i did not cut and paste! Thanks for the lessons.

root@rpi2:~ # ./get_temp
22
 
What is the math operand for multiplication if *=divide??

If I wanted to display Fahrenheit would that be the best spot or would that be best handled by localization/ preferences?
How about appending a "C" on the temp for now? Would that go on the printf line?
 
What is the math operand for multiplication if *=divide??
*= isn't divide, it's multiplication. 1e-3 is the same as 1/1000. I could have written buf /= 1000; or buf /= 1e3; instead of buf *= 1e-3.

If I wanted to display Fahrenheit would that be the best spot or would that be best handled by localization/ preferences? How about appending a "C" on the temp for now? Would that go on the printf line?
Sure, I wouldn't worry about localization/preferences etc for now. They are no fun.
 
I have this working but I am unsure if correct. The conversion number for Kelvin to Fahrenheit is in my comments but the working number is different. What am I doing wrong?

Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>
int main ()
{
        size_t size;
        int buf;
        size = sizeof buf;
        sysctlbyname("dev.ow_temp.0.temperature", &buf, &size, NULL, 0);
        buf -=224000; // 0 Kelvin == -459.67 F
        buf *= 1e-3;
        printf("%dF \n" , buf);
        return 0;
}


root@rpi2:~ # ./get_temp
70F
 
To convert Celsius to Fahreneit you need to apply the following formula:

Code:
F = (( C * 9 ) / 5 ) + 32

which may be coded as:
Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>
int main ()
{
       size_t size;
        int buf;
        size = sizeof buf;
        sysctlbyname("dev.ow_temp.0.temperature", &buf, &size, NULL, 0);
        buf -=273150;
        buf *= 1e-3;
        printf("%d C \n" , buf);  // remove this line if you don't want to print Celsius

        // convert Celsius to Fahreneit
        buf *= 9;
        buf /= 5;
        buf += 32;
        printf("%d F \n" , buf);

        return 0;
}
 
buf -=224000; // 0 Kelvin == -459.67 F buf *= 1e-3;
The reason that this doesn't work is that Fahrenheit and Kelvin are on different scales whereas Kelvin and Celsius are on the same scale just offset from each other. 1 °C more is the same increase in temperature as 1 K.

German Wikipedia has a pretty good temperature conversion table: https://de.wikipedia.org/wiki/Kelvin#Temperaturumrechnung

You can go directly from mK to Fahrenheit with: TF = (TmK * 1.8 / 1000) - 459.67

The mK->K->°C conversion we did already looses precision by cutting the decimal places. If you do the Fahrenheit conversion based on that value the error just grows. So I suggest doing something like this:
Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>

int
main()
{
        size_t size;
        int t_mK, t_C, t_F;
        size = sizeof t_mK;

        sysctlbyname("dev.cpu.0.temperature", &t_mK, &size, NULL, 0);

	t_C = (t_mK - 273150) / 1000;
	t_F = (t_mK * 1.8 / 1000) - 459.67;
        printf("%d mK, %d C, %d F\n", t_mK, t_C, t_F);

        return 0;
}
 
Back
Top