It is currently April 19th, 2024, 6:19 pm

Using HWiNFO with Rainmeter

Plugins and Addons popular with the Community
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using HWiNFO with Rainmeter

Post by jsmorley »

I'm not entirely convinced yet that the idea of selecting ALL sensor elements to be output in HWiNFO is the very best idea. I did that, going from 40 sensors output to 256. The amount of CPU used by HWiNFO every 2 seconds (its polling rate) went from 0.4% to 1.2%. I have a fast machine and the CPU use is trivial for me but I'm not entirely sure this is a good recommendation for every end-user.

I can see the charm in it however, since it means that no matter what skins I create or use that might need "other" sensors that I didn't select initially, it won't mess up the index numbers in all my other existing skins and require them to be "fixed".

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Variables]
Instance=HWiNFO64

[MeasureDelay]
Measure=Calc
Formula=MeasureDelay + 1
IfCondition=MeasureDelay > 4
IfTrueAction=[!UpdateMeasureGroup "Starting"][!Delay 2000][!UpdateMeasureGroup "Starting"]

[MeasureStartTime]
Measure=Time
Group=Starting
Disabled=1
Format=%H:%M:%S
UpdateDivider=-1

[MeasureCurrentTime]
Measure=Time
Format=%H:%M:%S

[MeasureUsedCPU_Starting]
Group=Starting
Measure=Plugin
Plugin=UsageMonitor
Alias=CPU
Name=#Instance#
UpdateDivider=-1

[MeasureUsedCPU]
Group=Starting
Measure=Plugin
Plugin=UsageMonitor
Alias=CPU
Name=#Instance#

[MeasureIDProcess]
Group=Starting
Measure=Plugin
Plugin=UsageMonitor
Category=Process
Counter=ID Process
Name=#Instance#

; Handles and Threads

[MeasureHandleCount_Starting]
Group=Starting
Measure=Plugin
Plugin=UsageMonitor
Category=Process
Counter=Handle Count
Name=#Instance#
UpdateDivider=-1

[MeasureHandleCount]
Group=Starting
Measure=Plugin
Plugin=UsageMonitor
Category=Process
Counter=Handle Count
Name=#Instance#

[MeasureThreadCount_Starting]
Group=Starting
Measure=Plugin
Plugin=UsageMonitor
Category=Process
Counter=Thread Count
Name=#Instance#
UpdateDivider=-1

[MeasureThreadCount]
Group=Starting
Measure=Plugin
Plugin=UsageMonitor
Category=Process
Counter=Thread Count
Name=#Instance#

; Memory

[MeasurePrivateBytes_Starting]
Group=Starting
Measure=Plugin
Plugin=UsageMonitor
Category=Process
Counter=Private Bytes
Name=#Instance#
UpdateDivider=-1

[MeasurePrivateBytes_Starting_Scaled]
Measure=Calc
Formula=MeasurePrivateBytes_Starting

[MeasurePrivateBytes]
Group=Starting
Measure=Plugin
Plugin=UsageMonitor
Category=Process
Counter=Private Bytes
Name=#Instance#

[MeasurePrivateBytes_Scaled]
Measure=Calc
Formula=MeasurePrivateBytes

[MeasureWorkingSet_Starting]
Group=Starting
Measure=Plugin
Plugin=UsageMonitor
Category=Process
Counter=Working Set
Name=#Instance#
UpdateDivider=-1

[MeasureWorkingSet_Starting_Scaled]
Measure=Calc
Formula=MeasureWorkingSet_Starting

[MeasureWorkingSet]
Group=Starting
Measure=Plugin
Plugin=UsageMonitor
Category=Process
Counter=Working Set
Name=#Instance#

[MeasureWorkingSet_Scaled]
Measure=Calc
Formula=MeasureWorkingSet

[MeasureWorkingSetPrivate_Starting]
Group=Starting
Measure=Plugin
Plugin=UsageMonitor
Category=Process
Counter=Working Set - Private
Name=#Instance#
UpdateDivider=-1

[MeasureWorkingSetPrivate_Starting_Scaled]
Measure=Calc
Formula=MeasureWorkingSetPrivate_Starting

[MeasureWorkingSetPrivate]
Group=Starting
Measure=Plugin
Plugin=UsageMonitor
Category=Process
Counter=Working Set - Private
Name=#Instance#

[MeasureWorkingSetPrivate_Scaled]
Measure=Calc
Formula=MeasureWorkingSetPrivate

; GPU

[MeasureInstanceGPU_Starting]
Measure=Plugin
Plugin=UsageMonitor
Group=Starting
Alias=GPU
Name=#Instance#
UpdateDivider=-1

[MeasureInstanceGPU]
Measure=Plugin
Plugin=UsageMonitor
Alias=GPU
Name=#Instance#

[MeasureInstanceVRAM_Starting]
Measure=Plugin
Plugin=UsageMonitor
Group=Starting
Alias=VRAM
Name=#Instance#
UpdateDivider=-1

[MeasureInstanceVRAM_Starting_Scaled]
Measure=Calc
Group=Starting
Formula=MeasureInstanceVRAM
UpdateDivider=-1

[MeasureInstanceVRAM]
Measure=Plugin
Plugin=UsageMonitor
Alias=VRAM
Name=#Instance#

[MeasureInstanceVRAM_Scaled]
Measure=Calc
Formula=MeasureInstanceVRAM

[MeasureInstanceVRAMSHARED_Starting]
Measure=Plugin
Plugin=UsageMonitor
Group=Starting
Alias=VRAMSHARED
Name=#Instance#
UpdateDivider=-1

[MeasureInstanceVRAMHARED_Starting_Scaled]
Measure=Calc
Group=Starting
Formula=MeasureInstanceVRAMSHARED_Starting
UpdateDivider=-1

[MeasureInstanceVRAMSHARED]
Measure=Plugin
Plugin=UsageMonitor
Group=Starting
Alias=VRAMSHARED
Name=#Instance#
UpdateDivider=-1

[MeasureInstanceVRAMHARED_Scaled]
Measure=Calc
Group=Starting
Formula=MeasureInstanceVRAMSHARED
UpdateDivider=-1

; Meters

[MeterBackground]
Meter=Image
W=320
H=261
SolidColor=0,0,0,255
SolidColor2=50,50,50,255
UpdateDivider=-1

[TextStyle]
FontSize=11
FontColor=200,200,200,255
AntiAlias=1

[LeftStyle]
X=5
Y=2R
StringAlign=Left

[NearRightStyle]
X=225
Y=0r
StringAlign=Right

[FarRightStyle]
X=315
Y=0r
StringAlign=Right

[MeterIDProcessL]
Meter=String
MeterStyle=TextStyle | LeftStyle
Y=5
Text=#Instance# (pid [MeasureIDProcess:0])
DynamicVariables=1

[MeterTime]
Meter=String
MeterStyle=TextStyle | LeftStyle
Y=10R
Text=Start / Current

[MeterStartTime]
Meter=String
MeterStyle=TextStyle | NearRightStyle
MeasureName=MeasureStartTime
Text=%1

[MeterCurrentTime]
Meter=String
MeterStyle=TextStyle | FarRightStyle
MeasureName=MeasureCurrentTime
Text=%1

[MeterUsedCPUL]
Meter=String
MeterStyle=TextStyle | LeftStyle
Y=10R
Percentual=1
NumOfDecimals=1
Text=Percent CPU

[MeterUsedCPUStarting]
Meter=String
MeterStyle=TextStyle | NearRightStyle
Text=[MeasureUsedCPU_Starting:1]%
DynamicVariables=1

[MeterUsedCPUCurrent]
Meter=String
MeterStyle=TextStyle | FarRightStyle
Text=[MeasureUsedCPU:1]%
DynamicVariables=1

[MeterHandleCountL]
Meter=String
MeterStyle=TextStyle | LeftStyle
Y=10R
Text=Handle Count

[MeterHandleCountStarting]
Meter=String
MeterStyle=TextStyle | NearRightStyle
MeasureName=MeasureHandleCount_Starting
Text=[MeasureHandleCount_Starting:0]
DynamicVariables=1

[MeterHandleCountCurrent]
Meter=String
MeterStyle=TextStyle | FarRightStyle
Text=[MeasureHandleCount:0]
DynamicVariables=1

[MeterThreadCountL]
Meter=String
MeterStyle=TextStyle | LeftStyle
Text=Thread Count

[MeterThreadCountStarting]
Meter=String
MeterStyle=TextStyle | NearRightStyle
Text=[MeasureThreadCount_Starting:0]
DynamicVariables=1

[MeterThreadCountCurrent]
Meter=String
MeterStyle=TextStyle | FarRightStyle
MeasureName=MeasureThreadCount
Text=[MeasureThreadCount:0]
DynamicVariables=1

[MeterPrivateBytesL]
Meter=String
MeterStyle=TextStyle | LeftStyle
Y=10R
Text=Private Bytes

[MeterPrivateBytesStarting]
Meter=String
MeterStyle=TextStyle | NearRightStyle
MeasureName=MeasurePrivateBytes_Starting_Scaled
AutoScale=1
NumOfDecimals=3
Text=%1

[MeterPrivateBytesCurrent]
Meter=String
MeterStyle=TextStyle | FarRightStyle
MeasureName=MeasurePrivateBytes_Scaled
AutoScale=1
NumOfDecimals=3
Text=%1

[MeterWorkingSetL]
Meter=String
MeterStyle=TextStyle | LeftStyle
Text=Working Set

[MeterWorkingSetStarting]
Meter=String
MeterStyle=TextStyle | NearRightStyle
MeasureName=MeasureWorkingSet_Starting_Scaled
AutoScale=1
NumOfDecimals=3
Text=%1

[MeterWorkingSetCurrent]
Meter=String
MeterStyle=TextStyle | FarRightStyle
MeasureName=MeasureWorkingSet_Scaled
AutoScale=1
NumOfDecimals=3
Text=%1

[MeterWorkingSetPrivateL]
Meter=String
MeterStyle=TextStyle | LeftStyle
Text=Working Set Private

[MeterWorkingSetPrivateStarting]
Meter=String
MeterStyle=TextStyle | NearRightStyle
MeasureName=MeasureWorkingSetPrivate_Starting_Scaled
AutoScale=1
NumOfDecimals=3
Text=%1

[MeterWorkingSetPrivateCurrent]
Meter=String
MeterStyle=TextStyle | FarRightStyle
MeasureName=MeasureWorkingSetPrivate_Scaled
AutoScale=1
NumOfDecimals=3
Text=%1

[MeterInstanceGPUL]
Meter=String
MeterStyle=TextStyle | LeftStyle
Y=10R
Text=Percent GPU

[MeterInstanceGPUStarting]
Meter=String
MeterStyle=TextStyle | NearRightStyle
Text=[MeasureInstanceGPU_Starting:1]%
DynamicVariables=1

[MeterInstanceGPUCurrent]
Meter=String
MeterStyle=TextStyle | FarRightStyle
AutoScale=1
NumOfDecimals=3
Text=[MeasureInstanceGPU:1]%
DynamicVariables=1

[MeterInstanceVRAMStartingL]
Meter=String
MeterStyle=TextStyle | LeftStyle
Y=10R
Text=Video RAM Private

[MeterInstanceVRAMStartingScaled]
Meter=String
MeterStyle=TextStyle | NearRightStyle
MeasureName=MeasureInstanceVRAM_Starting_Scaled
AutoScale=1
NumOfDecimals=3
Text=%1

[MeterInstanceVRAMCurrent]
Meter=String
MeterStyle=TextStyle | FarRightStyle
MeasureName=MeasureInstanceVRAM_Scaled
AutoScale=1
NumOfDecimals=3
Text=%1

[MeterInstanceVRAMSHAREDStartingL]
Meter=String
MeterStyle=TextStyle | LeftStyle
Text=Video RAM Shared

[MeterInstanceVRAMSHAREDStartingScaled]
Meter=String
MeterStyle=TextStyle | NearRightStyle
MeasureName=MeasureInstanceVRAMHARED_Starting_Scaled
AutoScale=1
NumOfDecimals=3
Text=%1

[MeterInstanceVRAMSHAREDCurrent]
Meter=String
MeterStyle=TextStyle | FarRightStyle
MeasureName=MeasureInstanceVRAMHARED_Scaled
AutoScale=1
NumOfDecimals=3
Text=%1

1.png
You do not have the required permissions to view the files attached to this post.
User avatar
raiguard
Posts: 660
Joined: June 25th, 2015, 7:02 pm
Location: The Sky, USA

Re: Using HWiNFO with Rainmeter

Post by raiguard »

I spun up a Lua script to parse the output of the command:

Lua script:

Code: Select all

function ParseOutput(measureName)
  local raw = SKIN:GetMeasure(measureName):GetStringValue()

  local output = ""

  -- Match over each group as a whole
  local match_string = "    Sensor(%d-)    .-    (.-)\n    .-    .-    (.-)\n    .-    .-    (.-)\n    .-    .-    (.-)\n    .-    .-    (.-)\n"
  for index, sensor, label, value, value_raw, color in raw:gmatch(match_string) do
    output = output
      .."\n"
      .."Index "..index.."\n"
      .."Sensor        "..sensor.."\n"
      .."Label         "..label.."\n"
      .."Value         "..value.."\n"
      .."ValueRaw      "..value_raw.."\n"
      .."Color         "..color.."\n"
  end

  -- Write to a file
  local file = io.open(SKIN:GetVariable("CURRENTPATH").."output.txt", "w")
  file:write(output)
  file:close()
end
Skin measures:

Code: Select all

[MeasureScript]
Measure = Script
ScriptFile = #@#HWiNFORegistryReader.lua

[MeasureQuery]
Measure = Plugin
Plugin = RunCommand
Parameter = reg query HKEY_CURRENT_USER\SOFTWARE\HWiNFO64\VSB
OutputType = UTF8
FinishAction = [!CommandMeasure MeasureScript "ParseOutput('#CURRENTSECTION#')"]
DynamicVariables = 1
IfCondition = 1
IfTrueAction = [!CommandMeasure #CURRENTSECTION# "Run"]
Snippet of output:

Code: Select all

Index 0
Sensor        System
Label         Virtual Memory Commited
Value         18,096 MB
ValueRaw      18096
Color         400040

Index 1
Sensor        System
Label         Virtual Memory Available
Value         12,026 MB
ValueRaw      12026
Color         408080

Index 2
Sensor        System
Label         Virtual Memory Load
Value         60.0 %
ValueRaw      60.0
Color         0080c0

Index 3
Sensor        System
Label         Physical Memory Used
Value         9,450 MB
ValueRaw      9450
Color         8080c0

Index 4
Sensor        System
Label         Physical Memory Available
Value         6,848 MB
ValueRaw      6848
Color         008080
”We are pretty sure that r2922 resolves the regression in resolution caused by a reversion to a revision.” - jsmorley, 2017
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using HWiNFO with Rainmeter

Post by jsmorley »

raiguard wrote: March 16th, 2021, 6:30 pm I spun up a Lua script to parse the output of the command:

Lua script:

Code: Select all

function ParseOutput(measureName)
  local raw = SKIN:GetMeasure(measureName):GetStringValue()

  local output = ""

  -- Match over each group as a whole
  local match_string = "    Sensor(%d-)    .-    (.-)\n    .-    .-    (.-)\n    .-    .-    (.-)\n    .-    .-    (.-)\n    .-    .-    (.-)\n"
  for index, sensor, label, value, value_raw, color in raw:gmatch(match_string) do
    output = output
      .."\n"
      .."Index "..index.."\n"
      .."Sensor        "..sensor.."\n"
      .."Label         "..label.."\n"
      .."Value         "..value.."\n"
      .."ValueRaw      "..value_raw.."\n"
      .."Color         "..color.."\n"
  end

  -- Write to a file
  local file = io.open(SKIN:GetVariable("CURRENTPATH").."output.txt", "w")
  file:write(output)
  file:close()
end
Skin measures:

Code: Select all

[MeasureScript]
Measure = Script
ScriptFile = #@#HWiNFORegistryReader.lua

[MeasureQuery]
Measure = Plugin
Plugin = RunCommand
Parameter = reg query HKEY_CURRENT_USER\SOFTWARE\HWiNFO64\VSB
OutputType = UTF8
FinishAction = [!CommandMeasure MeasureScript "ParseOutput('#CURRENTSECTION#')"]
DynamicVariables = 1
IfCondition = 1
IfTrueAction = [!CommandMeasure #CURRENTSECTION# "Run"]
Snippet of output:

Code: Select all

Index 0
Sensor        System
Label         Virtual Memory Commited
Value         18,096 MB
ValueRaw      18096
Color         400040

Index 1
Sensor        System
Label         Virtual Memory Available
Value         12,026 MB
ValueRaw      12026
Color         408080

Index 2
Sensor        System
Label         Virtual Memory Load
Value         60.0 %
ValueRaw      60.0
Color         0080c0

Index 3
Sensor        System
Label         Physical Memory Used
Value         9,450 MB
ValueRaw      9450
Color         8080c0

Index 4
Sensor        System
Label         Physical Memory Available
Value         6,848 MB
ValueRaw      6848
Color         008080
Looks really good. I'd lose the "Color" entries. Those were there for the old Windows Sidebar Gadget.
User avatar
SilverAzide
Rainmeter Sage
Posts: 2604
Joined: March 23rd, 2015, 5:26 pm

Re: Using HWiNFO with Rainmeter

Post by SilverAzide »

OK, I think I found an issue.

If a sensor isn't active, then HWiNFO will not output the sensor entries into the registry. If the sensor does become active, then the registry entries are created and indexes can be shifted.

For example: Fans. If you start HWiNFO and your CPU/GPU fan isn't spinning, then there is no data in the sensors panel. Once the fans start spinning, then the entries appear and all the indexes that follow the fan entry will shift/increment downward. (This is normal HWiNFO behavior, but entry IDs in the plug-in were unique and didn't shift around.)

This applies to batteries, network devices, plugging/unplugging drives, etc., anything that can appear AFTER HWiNFO is started. Once HWiNFO is running, things won't disappear from the sensors panel.

Thoughts?
Gadgets Wiki GitHub More Gadgets...
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using HWiNFO with Rainmeter

Post by jsmorley »

SilverAzide wrote: March 16th, 2021, 10:47 pm OK, I think I found an issue.

If a sensor isn't active, then HWiNFO will not output the sensor entries into the registry. If the sensor does become active, then the registry entries are created and indexes can be shifted.

For example: Fans. If you start HWiNFO and your CPU/GPU fan isn't spinning, then there is no data in the sensors panel. Once the fans start spinning, then the entries appear and all the indexes that follow the fan entry will shift/increment downward. (This is normal HWiNFO behavior, but entry IDs in the plug-in were unique and didn't shift around.)

This applies to batteries, network devices, plugging/unplugging drives, etc., anything that can appear AFTER HWiNFO is started. Once HWiNFO is running, things won't disappear from the sensors panel.

Thoughts?
Yike. That's a bit ugly. I have emailed Martin to see what he thinks.

Seems to me that we need to encourage folks to create the variables for the indexes after everything that will be running is running on their system. So what I'm hearing is that things might "appear" on the panel and get an index, like a USB drive and such. That can and will move all the index numbers below them. However, once things are recognized, they won't "disappear" from the panel if you disconnect them?

Just out of curiosity, I don't see how HWiNFO can be running and your CPU and / or GPU fan(s) are not?
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using HWiNFO with Rainmeter

Post by jsmorley »

raiguard,

How about this?

Lua:

Code: Select all

function ParseOutput(measureName)
	local raw = SKIN:GetMeasure(measureName):GetStringValue()
	local fileName = SKIN:GetVariable('CURRENTPATH')..'output.html'
  
  -- Create document header
	local output = 
	[[<!DOCTYPE HTML>
	<html lang="en-US">
	<head>
	<title>HWiNFO Registry Reader</title>
	<meta http-equiv="content-type" content="text/html;charset=utf-8" />
	<style>
	body {
		font-family: Sans-serif;
		font-size: 100%;
		font-color: #2F2F2F;
		background-color: #E1E3E6;
	}
	td {
		padding: 5px;
	}
	th {
		background-color: #F7BC81;
		color: #2F2F2F;
		padding: 10px 0px 10px 0px;
	}
	table {
		table-layout: fixed;
		width: 100%;
		background-color: #FAFAFA;
		box-shadow: 0 0 15px 3px #9E9E9E;
	}
	table, th, td {
		border-style: solid;
		border-width: 1px;
		border-color: #2F2F2F;
		border-collapse: collapse;    
		word-wrap: break-word;
	}
	div {
		width: 95%;
		position: absolute;
		top:0;
		bottom: 0;
		left: 0;
		right: 0;
		margin: auto;
	}  
	</style>
	</head>
	<body>
	<div>
	<br>
	<table>
	<tr>
	<th style="width: 5%;">Index</th>
	<th style="width: 25%;">Sensor</th>
	<th style="width: 25%;">Label</th>
	<th style="width: 10%;">Value</th>
	<th style="width: 10%;">ValueRaw</th>
	</tr>]]

	-- Match over each group as a whole
	local match_string = '    Sensor(%d-)    .-    (.-)\n    .-    .-    (.-)\n    .-    .-    (.-)\n    .-    .-    (.-)\n'
	for index, sensor, label, value, value_raw in raw:gmatch(match_string) do
		output = output
		..'<tr><td style="width: 5%;">'..index..'</td>'
		..'<td style="width: 25%;">'..sensor..'</td>'
		..'<td style="width: 25%;">'..label..'</td>'
		..'<td style="width: 10%;">'..value..'</td>'
		..'<td style="width: 10%;">'..value_raw..'</td></tr>\n'
	end

	-- Write document footer
	output = output .. '</table><br></div></body></html>'

	-- Write to the file
	local file = io.open(fileName, 'w')
	file:write(output)
	file:close()
  
	-- Open the page in the browser

	SKIN:Bang(fileName)
  
end

1.png
You do not have the required permissions to view the files attached to this post.
User avatar
SilverAzide
Rainmeter Sage
Posts: 2604
Joined: March 23rd, 2015, 5:26 pm

Re: Using HWiNFO with Rainmeter

Post by SilverAzide »

jsmorley wrote: March 16th, 2021, 10:54 pm Just out of curiosity, I don't see how HWiNFO can be running and your CPU and / or GPU fan(s) are not?
Ah, yes. I use laptops, so the various fans don't kick on until things get toasty.
Gadgets Wiki GitHub More Gadgets...
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using HWiNFO with Rainmeter

Post by jsmorley »

SilverAzide wrote: March 16th, 2021, 11:06 pm Ah, yes. I use laptops, so the various fans don't kick on until things get toasty.
Well crap... I'd like to see what Martin thinks. This sounds prickly.
User avatar
SilverAzide
Rainmeter Sage
Posts: 2604
Joined: March 23rd, 2015, 5:26 pm

Re: Using HWiNFO with Rainmeter

Post by SilverAzide »

jsmorley wrote: March 16th, 2021, 11:08 pm Well crap... I'd like to see what Martin thinks. This sounds prickly.
After pondering a bit, if Martin doesn't want to change anything, then perhaps a work-around would be a really lightweight plugin that is basically a Registry wrapper. Instead of taking an index, you'd pass it the Sensor and Label and it would look up the value. It could act like the old plugin and return a -9xxx number for a missing sensor or just zero if you don't care.

[MeasureFanSpeed]
Measure=Plugin
Plugin=whatever
SensorName="COMPAL EC: Alienware 17 R3"
Label="CPU"

etc....?
Gadgets Wiki GitHub More Gadgets...
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Using HWiNFO with Rainmeter

Post by jsmorley »

SilverAzide wrote: March 16th, 2021, 11:14 pm After pondering a bit, if Martin doesn't want to change anything, then perhaps a work-around would be a really lightweight plugin that is basically a Registry wrapper. Instead of taking an index, you'd pass it the Sensor and Label and it would look up the value. It could act like the old plugin and return a -9xxx number for a missing sensor or just zero if you don't care.

[MeasureFanSpeed]
Measure=Plugin
Plugin=whatever
SensorName="COMPAL EC: Alienware 17 R3"
Label="CPU"

etc....?
Yeah, I have a bad feeling that that might well end up being the answer. I suspect Martin is not going to want to potentially break, or to be honest even change, the prehensile-tail "gadget" functionality there.

I think I'd hold off on distributing any skins using this until we get this settled...

It might just be more complicated to do than you think. The Registry is very "hierarchical" in nature, and searching it is based on the key name, which today is the "index". Searching it based on "values" instead might be very, very slow. I think what we might have to do is to use a plugin that just gets that entire subkey of HKEY_CURRENT_USER\SOFTWARE\HWiNFO64\VSB into memory in the plugin, and then searches just that to reconcile the SensorName / Label combination above and get the Value / ValueRaw.