Other sysctl ow_temp in a GTKwindow

Phishfry

Beastie's Twin

Reaction score: 3,220
Messages: 6,348

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?
 
OP
Phishfry

Phishfry

Beastie's Twin

Reaction score: 3,220
Messages: 6,348

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.
 
OP
Phishfry

Phishfry

Beastie's Twin

Reaction score: 3,220
Messages: 6,348

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:~ #
 
OP
Phishfry

Phishfry

Beastie's Twin

Reaction score: 3,220
Messages: 6,348

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.
 

tobik@

Daemon
Developer

Reaction score: 1,432
Messages: 1,909

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;
}
 
OP
Phishfry

Phishfry

Beastie's Twin

Reaction score: 3,220
Messages: 6,348

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.
 
A

ASX

Guest


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);
 

tobik@

Daemon
Developer

Reaction score: 1,432
Messages: 1,909

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
 
OP
Phishfry

Phishfry

Beastie's Twin

Reaction score: 3,220
Messages: 6,348

Perfect! Well you can tell i did not cut and paste! Thanks for the lessons.

root@rpi2:~ # ./get_temp
22
 
OP
Phishfry

Phishfry

Beastie's Twin

Reaction score: 3,220
Messages: 6,348

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?
 

tobik@

Daemon
Developer

Reaction score: 1,432
Messages: 1,909

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.
 
OP
Phishfry

Phishfry

Beastie's Twin

Reaction score: 3,220
Messages: 6,348

Some notes for GTK3 ARM compiling.
GTK Header file needs full path
#include </usr/local/include/gtk-3.0/gtk/gtk.h>

pkg-config is no longer available (has been superseded). Use pkgconf as a direct replacment.
cc `pkgconf --cflags gtk+-3.0` main.c -o owgui `pkgconf --libs gtk+-3.0` -rdynamic -Wall

http://prognotes.net/2015/06/gtk-3-c-program-using-glade-3/
 
OP
Phishfry

Phishfry

Beastie's Twin

Reaction score: 3,220
Messages: 6,348

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
 
A

ASX

Guest


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;
}
 

tobik@

Daemon
Developer

Reaction score: 1,432
Messages: 1,909

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;
}
 
Top