uncle-meat / open-hardware-monitor

Automatically exported from code.google.com/p/open-hardware-monitor
0 stars 0 forks source link

Provide sensor information via WMI, Registry or IPC to other processes #62

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
This is feature suggestion.
Windows WMI service is standard way that other program (including script
programs) can access/retrieve wide range of system information regarding PC
hardware and software. OHM provides very valuable system information so I
think that it can be good WMI service provider. Current version of MS WMI
does not implement statistics like CPU temperature, fan speed, etc.

Some other programs that monitor hardware/CPU temperature provide such
information via shared memory (Hardware Monitor from CPUID)  or WMI service
(Hardware Sensors Monitor/SpeedFan). Or alternatively, OHM can add a
Active-X control code that enables access to the informations it generates.
I prefer WMI service provider because it is easier to use for the script
program like Windows Sidebar gadgets.

If OHM will add WMI provider support, I can contribute Windows Sidebar
gadget code that utilizes such service to this project.

Original issue reported on code.google.com by cant...@gmail.com on 24 May 2010 at 11:30

GoogleCodeExporter commented 9 years ago
I have not yet analyzed in detail what is needed to implement a WMI provider in 
.NET
2.0. Things could be simplified in .NET 3.5, but I am not sure if it is worth to
raise the requirements just for WMI.

Other alternatives are writing the sensor data to the Registry or exposing it 
via
IPC. The Registry should be easy to implement, but it would not be very 
efficient and
a bit limited.

I have not yet decided which interface is the best choice here.

Original comment by moel.mich on 25 May 2010 at 8:29

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Moel can see my deleted comments, so he will already know, but I am working on 
making the existing dll usable by other processes. Now, this is not the same as 
a wmi provider as you need to link your own application to the dll and not rely 
on the main executable to forward the information.

I made some progress, it's been mostly making allot of 
interfaces/classes/structures public instead of internal, I'm not a c# 
programmer so I just have to go through all the inheritances and try a compile 
ect ect. Still not there, not how I want it to be atleast ( I would like to be 
able to use it not only as sensor information provider but just as generic hw 
identification as well and yes that is possible with the sensor event as I 
exposed the hardware type's more, as well with the hardwareadded event handler 
as again I exposed the internal classes/interfaces so I can cast them but 
that's the thing, I don't want to have to cast them I want the hardware to be 
provided exactly as is: an intel cpu should be an intel cpu in hardwareadded 
event, not a generic hardware interface which doesn't expose anything.

But ok casting works so far. My problem now is the sensor readings don't seem 
ok. Temperatures/fan's/clocks all match, but cpu load max is almost always 100 
after a few loops :( I have to go in and check that I did not expose something 
in the cpuload class which I should not have, something which is referencing 
itself now or something alike. Also, for debugging purposes I'm feeding the 
values in a listbox, makes me admire that aga treeview as my listbox isn't 
coming close to being as pretty ( I won't need an extensive interface, I am 
filtering hardware after computer.open to match that of a folding client so 
I'll be using only a few of the sensors and will report them with I think a 
small zedgraph ( easy  way out ). 

I would attach a file here but I won't as I'm not ready and it's abit of a mess 
the way it is. I'd rather show something which works, might take a couple of 
days ( though if you like me only want to expose the information and leave the 
sorting it out to whoever wants to use it, doing as I am doing is a quick fix 
and I'm quite sure you would know how to expose the hardware interface's better 
then I have done with just making a few structs/classes/interfaces public.

Original comment by mtm78.cf...@gmail.com on 11 Oct 2010 at 11:55

GoogleCodeExporter commented 9 years ago
Well I had a look at creating a WMI provider, and it's really not as much work 
as originally thought. It's in fact relatively simple, because we already use 
unique identifiers for each sensor. I haven't gotten round to it yet, but it 
can be fairly dynamically by simply adding an extra UpdateVisitor to update the 
WMI objects.

The hard part is structuring it. There are several options, but the biggest 
choice is whether to choose between using the identifiers straight up, or 
boiling them down to more generic ones. In a few cases an identifier includes a 
typename. Either way, client apps will have to iterate over the available 
sensors anyway.

A third option would be to do it Everest style: use hardcoded, fixed 
identifiers. That leaves out exotic hardware though, something I personally 
don't really want to do.

Original comment by paulwere...@gmail.com on 12 Oct 2010 at 6:30

GoogleCodeExporter commented 9 years ago
You don't need to change any of the internal classes to public only for 
accessing the sensor information. The Open Hardware Monitor GUI application 
just uses only the public classes and the public interfaces. You can look at 
the source in the GUI namespace to see how it is used there. To know what type 
of hardware is behind an IHardware interface you can use the HardwareType enum 
(similar to the SensorType enum). To identify a hardware with a unique string 
you can use the Identifier property. 

Hiding the actual classes behind interfaces has the advantage, that we can 
change these classes without breaking the library interface. Beside this, one 
can access the interface in a unified way.

More detailed information about each hardware is currently not exposed, because 
right now only the minimal things required for sensor reading are collected. 

Original comment by moel.mich on 12 Oct 2010 at 6:37

GoogleCodeExporter commented 9 years ago
Hardware type enum only exposes cpu, nvidia, ati, mainboard, heatmaster etc. I 
wanted acces to the internal cpu type's recognized ( eg 
intel/amd-&H10/&H8/generic cpu ), or even more specific the cpuid information 
gathered as I would not have to use wmi win32_processor queries.

Also, my main concern is, I want to be able to open the Computer, making the 
library identify all the hardware which I can then read out using properties or 
structures or interfaces doesn't matter as long as there is more detailed 
information available without using .getreport and parsing the stringoutput. 
Yes, I would only have to do that once and it would work, but it's not really 
what I wanted. String parsing instead of having the hardware exposed more is 
not what I would like, but I think my use of library is other then the intended 
one.

I think I will use the report function and stop messing around in the library. 
I have to say I really really like this project, it's the only .net native lib 
able to gather this information, and also the only open source library which 
does this. If you would extend the library to be easier to use as generic hw 
reporting lib it would only increase the usefulness further though.

The message above from paulwerelds is exactly the issue I have, structuring the 
information being returned from the library. Even better would it be if the 
library itself could be intitialized, and then queried for detected hardware, 
and then have functions to enable sensor readings for each one. Now you can do 
this but it's not the easiest thing to do as you have to parse string output 
for detailed information, 

If you use hardware added

{{{
Public Class Form1
    Private WithEvents ohmComp As New Computer
    Private _colSensors As New Collection
    Private iVisitor As OpenHardwareMonitor.Hardware.IVisitor
    Private iHandler As New OpenHardwareMonitor.Hardware.SensorEventHandler(AddressOf SensorEvenentHandler)

    Public Sub SensorEvenentHandler(ByVal Sensor As OpenHardwareMonitor.Hardware.Sensor)
        Try
            For Each lvItem As ListViewItem In lv.Items
                If lvItem.Tag = Sensor.Identifier.ToString Then
                    '.SubItems.Add(nSensor.Value)
                    '.SubItems.Add(nSensor.Max)
                    '.SubItems.Add(nSensor.Min)
                    'lvItem.Text = Sensor.Name
                    'lvItem.SubItems(1).Text = Sensor.SensorType.ToString
                    lvItem.SubItems(2).Text = Sensor.Value
                    If Not Sensor.Min Is Nothing Then
                        lvItem.SubItems(3).Text = Sensor.Min
                    Else
                        lvItem.SubItems(3).Text = "0"
                    End If
                    If Not Sensor.Max Is Nothing Then
                        lvItem.SubItems(4).Text = Sensor.Max
                    Else
                        lvItem.SubItems(4).Text = "0"
                    End If

                    Exit For
                End If
            Next
            lv.Refresh()
        Catch ex As Exception

        End Try
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        lv.HeaderStyle = ColumnHeaderStyle.Nonclickable
        iVisitor = New SensorVisitor(iHandler)
        ohmComp.Open()

    End Sub

    Private Sub ohmComp_HardwareAdded(ByVal hardware As OpenHardwareMonitor.Hardware.IHardware) Handles ohmComp.HardwareAdded
        Try
            If hardware.HardwareType = HardwareType.CPU Then
                rt.AppendText("Found cpu: " & hardware.Name & vbNewLine)
                Dim iCpu As OpenHardwareMonitor.Hardware.CPU.GenericCPU = TryCast(hardware, OpenHardwareMonitor.Hardware.CPU.GenericCPU)
                rt.AppendText("Family:" & iCpu.family & " Model:" & iCpu.model & " Stepping:" & iCpu.stepping & vbNewLine)
                rt.AppendText("Available cores: " & iCpu.coreCount & " Threads per core:" & iCpu.cpuid.First.Length & vbNewLine)
                rt.AppendText("Trying to attach to sensor information... " & vbNewLine)
                For xint As Int16 = 0 To iCpu.Sensors.Count - 1
                    If ReferenceEquals(iCpu.Sensors(xint).Hardware, hardware) Then
                        rt.AppendText("Sensor name: " & iCpu.Sensors(xint).Name & " Type: " & iCpu.Sensors(xint).SensorType.ToString & " Value: " & iCpu.Sensors(xint).Value & vbNewLine)
                        Dim nSensor As Sensor = iCpu.Sensors(xint)
                        _colSensors.Add(nSensor, nSensor.Identifier.ToString)
                        Dim lvItem As New ListViewItem
                        With lvItem
                            .Tag = nSensor.Identifier.ToString
                            .Text = nSensor.Name
                            .SubItems.Add(nSensor.SensorType.ToString)
                            .SubItems.Add(nSensor.Value)
                            .SubItems.Add(nSensor.Min)
                            .SubItems.Add(nSensor.Max)
                        End With
                        lv.Items.Add(lvItem)
                    End If
                Next

            End If

        Catch ex As Exception

        End Try
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        For Each Sensor As Sensor In _colSensors
            Sensor.Hardware.Update()
            Sensor.Accept(iVisitor)
        Next
    End Sub
}}}

The listview is a temp thing just used to check the output, and yes I realize 
the identifier can be used to group sensors as well but it does not allow me 
check the number of threads per core, not does it allow me to get any of cpu 
information like family/model/revision which are all pretty generic.

You can see I am using hardwareadded with casting to be able to read some 
values directly, I really want to be able to only update those sensors I need 
the values from ( I am trying to bind this monitoring lib to a console client 
wrapper for folding@home, so I really do not need to go through all sensors it 
will only be 'waisted' cycles ). But, being able to bind the sensors directly I 
need more information about the underlaying hardware. For instance with a gpu, 
I need the busid or other information I can try and match with the output of 
openclnet which I use to enum folding capable gpu's. I really want as much 
information as possible to be combined, it would make data mining much more 
efficient. There is no other open source initiative which is doing what 
openhardwaremonitor does, or I haven't been able to find it. The thing which 
comes close, or maybe surpasses it, is the cpuid engine -> 
http://www.cpuid-pro.com/hwmonitor.php, that's a commercial solution so it's 
not an option for me though.

Look I understand my 'request' is not something you can or even should do, I 
think that you would need to restructure the dll entirely so that it is not 
centered around the sensorvisitor interface ( which naturally is the intent of 
the dll right now ). So don't see this as a request just a remark from someone 
who is trying to use the lib in a way you did not have in mind when designing 
it.

Original comment by mtm78.cf...@gmail.com on 12 Oct 2010 at 11:20

GoogleCodeExporter commented 9 years ago
Here's a few approaches we could take for the WMI route, well worth discussing 
because the implementation is pretty straight forward, but the definition is 
quite important and has to be well thought through. For all cases the root 
namespace is /root/ohm.

The first method can be achieved with about 50 lines of code, very quick and 
dirty. Within the root namespace we simply declare a Sensor class, which then 
has a number of fixed attributes: Name, Type, Value, etcetera. Optionally we 
include the HardwareType and Name of its parent hardware. All this requires is 
mapping ISensor to the WMI-exposed Sensor class, taking the appropriate 
conversions into consideration (Identifier/Type become strings). For each 
sensor in the system, an instance of this class is added, which can then be 
enumerated by any application that wishes to use it. Any separation between 
hardware and/or sensor types has to be done entirely in the client application.

We could also declare a subnamespace based on HardwareType the Sensor belongs 
to, and create multiple instances of a Sensor class under this namespace. Gives 
it slightly more structure and adds a level of separation, but in essence there 
is not much difference in the way it has to be handled in any client 
applications. This would result in /root/ohm/mainboard or /root/ohm/amdgpu 
having multiple instances of the Sensor class.
Same thing could be done for SensorType. This would result in 
/root/ohm/temperature or /root/ohm/clock - in this case, HardwareType would 
have to be encapsulated in the Sensor class again.

We could also create multiple Sensor classes, each with their own specific set 
of properties. We could then still take any of the approaches above.

Quite frankly, I think the first approach is actually almost the best course to 
take, as it gives client applications absolute freedom in how to handle the 
data. By supplying the HardwareType and SensorType as properties of each sensor 
instance they can also easily separate them in any way they wish. In case we 
add new hardware and/or sensortypes, we have to do absolutely nothing other 
than documenting them if needed. The only drawback is that each of these 
classes will have a pretty substantial number of properties to deal with, but 
again - we're only the content provider, we're not the ones that should decide 
where things go or how they're formatted.

Original comment by paulwere...@gmail.com on 12 Oct 2010 at 11:20

GoogleCodeExporter commented 9 years ago
Hello all, 

just discovered OVM this morning and already loving it, great job !
Would also indeed be very interested by a WMI Provider; this would allow to 
pipe all the sensors data onto my ASP webpage; would be very usefull

cheers

Original comment by thierrys...@gmail.com on 2 Dec 2010 at 2:50

GoogleCodeExporter commented 9 years ago
Paul Werelds has already written a WMI implementation for the Open Hardware 
Monitor. You can find it in the latest SVN. A documentation can be downloaded 
here http://ohm.werelds.net/OpenHardwareMonitor-WMI.pdf

Original comment by moel.mich on 2 Dec 2010 at 3:29

GoogleCodeExporter commented 9 years ago
Just wanted to say thanks, the interface's are now complete enough to be used 
in any external application ( through importing openhardwaremonitorlib.dll 
directly ).

That was what I wanted/needed, and it's fully working now and I really just 
wanted to say thank you for your excellent application/library!

Original comment by mtm78.cf...@gmail.com on 2 May 2011 at 9:04