It is currently March 28th, 2024, 8:29 pm

Round 4 Core CPU Meter

Skins that monitor system information
User avatar
DavidRGreen
Posts: 35
Joined: May 5th, 2020, 10:19 am

Round 4 Core CPU Meter

Post by DavidRGreen »

This Widget, designed to sit discretely in a corner of the desktop reflects the CPU core usage as an arc per core, outer being #1 through to inner being #4. The line colour will change depending on the CPU core usage; length of arc, starting at a green colour though to red (for "red lining").

The percentile value at the bottom reflects the whole CPU average.

Image

As this was my first (significant) widget developed, I had a little help from balala in sorting out some of the code. (Thanks!)
Round CPU Meter_1.0.rmskin
Since first posting this, balala made some suggestions, which were implemented, perhaps not quite as he envisioned them, jsmoreley offered some insight as well. Cosmetically, it is still much the same, only now supports up to 8 cores, via 2 widgets, one for 1-4 cores where each core is represented by a 225° arc, and one for 1-8 cores where each core is represented by a 135° arc. In both cases, non-present cores are neither monitored nor displayed.
Round CPU Meter_2.2.rmskin
It's been an interesting learning experience, and maybe others will discover something new in these widgets too.
You do not have the required permissions to view the files attached to this post.
Last edited by DavidRGreen on June 3rd, 2020, 1:54 pm, edited 1 time in total.
User avatar
balala
Rainmeter Sage
Posts: 16110
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Round 4 Core CPU Meter

Post by balala »

Looking good, congratulations. However there is a small improvement, which you could easily do and me personally at least, definitely recommend it.
Since not all processors have four cores, you should achieve the skin to show the appropriate number of Roundline meters, depending on the number of cores. You should choose a number of cores up to which the skin should show the correct number of meters. Not to modify too much the code, starting from the size of the existing meters, this number should be 8. If you want more, you have to increase the diameter of the Roundline meters.
Interested? If you are and you don't know how to achieve it, please let me know, for assistance.
User avatar
DavidRGreen
Posts: 35
Joined: May 5th, 2020, 10:19 am

Re: Round 4 Core CPU Meter

Post by DavidRGreen »

Thanks balala,

Actually, your suggestion is not totally unexpected. And I already have an idea on an implementation solution that will not impact its dimensions.
Ironically, when I first built this widget, many years ago, I only had a dual-core computer, but built it for a quad, and it was still 'good to go' when I upgraded to a quad-core machine.

Of course, Octo-core is all very well, but after that? Visualisation after that may become an overkill… Maybe…

Stay tuned for Updates :)
User avatar
balala
Rainmeter Sage
Posts: 16110
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Round 4 Core CPU Meter

Post by balala »

DavidRGreen wrote: May 24th, 2020, 3:20 am Of course, Octo-core is all very well, but after that? Visualisation after that may become an overkill… Maybe…
Yep, but you could increase the diameter of the skin or whatever. It's up to you, you being the author.
DavidRGreen wrote: May 24th, 2020, 3:20 am Stay tuned for Updates :)
Alright.
User avatar
DavidRGreen
Posts: 35
Joined: May 5th, 2020, 10:19 am

Round 4, 6 & 8 Core CPU Meter

Post by DavidRGreen »

Okay, now we have 4, 6 & 8 Core CPU meters.

Image

I don't actually have an 8 core CPU on my computer, so my first thought was, "What are those extra lines doing there?"
I did check my system specs, and yes, I only have four, so them I checked the log, and all was revealed… Instead on yielding a return value of zero for non-existant cores (like it used to under XWidget), Rainmeter is populating the empty core values with the average (ie. Core 0).

I'd prefer a zero (or -1) for a null core, a -1 value would be detectable and actioned accordingly, but anyway…
Round CPU Meter_2.0.rmskin
So there it is, up to 8 cores, and still the same size, discrete and unimposing on desktop acreage.
You do not have the required permissions to view the files attached to this post.
User avatar
balala
Rainmeter Sage
Posts: 16110
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Round 4, 6 & 8 Core CPU Meter

Post by balala »

DavidRGreen wrote: May 26th, 2020, 2:33 am I don't actually have an 8 core CPU on my computer,
Doesn't matter, if you're publishing your skin either here on the forum, or on DA, it is much better to have a skin which could be properly usable by as much users as possible.
DavidRGreen wrote: May 26th, 2020, 2:33 am so my first thought was, "What are those extra lines doing there?"
I did check my system specs, and yes, I only have four, so them I checked the log, and all was revealed… Instead on yielding a return value of zero for non-existant cores (like it used to under XWidget), Rainmeter is populating the empty core values with the average (ie. Core 0).
Exactly, that's how the Rainmeter's CPU measures are working.
DavidRGreen wrote: May 26th, 2020, 2:33 am I'd prefer a zero (or -1) for a null core, a -1 value would be detectable and actioned accordingly, but anyway…
Yep, but it anyway is detectable and the appropriate number of meters should be shown.
For instance, add the following measure to your code:

Code: Select all

[MeasureRun]
Measure=Plugin
Plugin=RunCommand
Parameter=WMIC CPU Get NumberOfLogicalProcessors
State=Hide
OutputType=ANSI
RegExpSubstitute=1
Substitute="\n":"","\s":"",".*(\d{1,2})":"\1"
IfCondition=([#CURRENTSECTION#]=1)
IfTrueAction=[!ShowMeter "DisplayCPU1"][!HideMeter "DisplayCPU2"][!HideMeter "DisplayCPU3"][!HideMeter "DisplayCPU4"][!HideMeter "DisplayCPU5"][!HideMeter "DisplayCPU6"][!HideMeter "DisplayCPU7"][!HideMeter "DisplayCPU8"]
IfCondition2=([#CURRENTSECTION#]=2)
IfTrueAction2=[!ShowMeter "DisplayCPU1"][!ShowMeter "DisplayCPU2"][!HideMeter "DisplayCPU3"][!HideMeter "DisplayCPU4"][!HideMeter "DisplayCPU5"][!HideMeter "DisplayCPU6"][!HideMeter "DisplayCPU7"][!HideMeter "DisplayCPU8"]
IfCondition3=([#CURRENTSECTION#]=4)
IfTrueAction3=[!ShowMeter "DisplayCPU1"][!ShowMeter "DisplayCPU2"][!ShowMeter "DisplayCPU3"][!ShowMeter "DisplayCPU4"][!HideMeter "DisplayCPU5"][!HideMeter "DisplayCPU6"][!HideMeter "DisplayCPU7"][!HideMeter "DisplayCPU8"]
IfCondition4=([#CURRENTSECTION#]=6)
IfTrueAction4=[!ShowMeter "DisplayCPU1"][!ShowMeter "DisplayCPU2"][!ShowMeter "DisplayCPU3"][!ShowMeter "DisplayCPU4"][!ShowMeter "DisplayCPU5"][!ShowMeter "DisplayCPU6"][!HideMeter "DisplayCPU7"][!HideMeter "DisplayCPU8"]
IfCondition5=([#CURRENTSECTION#]=8)
IfTrueAction5=[!ShowMeter "DisplayCPU1"][!ShowMeter "DisplayCPU2"][!ShowMeter "DisplayCPU3"][!ShowMeter "DisplayCPU4"][!ShowMeter "DisplayCPU5"][!ShowMeter "DisplayCPU6"][!ShowMeter "DisplayCPU7"][!ShowMeter "DisplayCPU8"]
DynamicVariables=1
When you refresh / load the skin, this measure has to be run, so add the following option to the [Rainmeter] section: OnRefreshAction=[!CommandMeasure "MeasureRun" "Run"].
A few other possible improvements I'd do on your code:
  • Additionally I'd add a Hidden=1 option to all Roundline meters ([DisplayCPU1] - [DisplayCPU8]). The appropriate number of meters are revealed when the RunCommand plugin measure is run.
  • I'd create a style section and would gather all commonly used options into such a style section. For instance a [RoundlineStyle] section should be created and the common Solid=1, AntiAlias=1, W=100 and H=100 options should be removed from all Roundline meters and moved there. Finally a MeterStyle=RoundlineStyle option should be added to all those Roundline meters, to let them get and use the options of the style section.
  • Whenever are you working with a skin which has no background, it is a good idea to add to the [Rainmeter] section, beside the existing options, the following ones as well:

    Code: Select all

    [Rainmeter]
    ...
    BackgroundMode=2
    SolidColor=0,0,0,1
    These options are creating a completely transparent background, but which reacts to mouse clicks and right-clicks.
User avatar
DavidRGreen
Posts: 35
Joined: May 5th, 2020, 10:19 am

Re: Round 4 Core CPU Meter

Post by DavidRGreen »

balala wrote: May 26th, 2020, 10:06 am it is much better to have a skin which could be properly usable by as much users as possible
Well, I can't argue with that, although you'd have to admit that the creation of a widget would involve a degree of self-interest, which would then expand to a wider audience, if so inclined. I've still got training wheels deployed here, and still trying to get my head around the 'Rainmeter way'.
balala wrote: May 26th, 2020, 10:06 am that's how the Rainmeter's CPU measures are working
… I'm still encumbered with expectations based on prior widget engine experience :)

Your code suggestion looks interesting.
I'm guessing that OnRefreshAction= limits the section's execution to load time only. It doesn't look like the sort of thing that you would want running at every update cycle. And it's a lot of Bags there.
Technically, hiding and showing CPU #1 is a little redundant. You'll need a least 1 CPU core to actually do anything, for without at least 1 CPU, your computer will be an inert circuit board…

"Styles" look interesting. I just haven't read all the documentation yet. I'll get there eventually.

And BTW, SolidColor=0,0,0,1 is not "completely transparent", it is ¹/₂₅₅ opaque! :)

Thanks balala
User avatar
balala
Rainmeter Sage
Posts: 16110
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Round 4 Core CPU Meter

Post by balala »

DavidRGreen wrote: May 26th, 2020, 1:31 pm I'm guessing that OnRefreshAction= limits the section's execution to load time only. It doesn't look like the sort of thing that you would want running at every update cycle. And it's a lot of Bags there.
Well, usually the number of cores doesn't change while you're running the skin, so... 8-)
DavidRGreen wrote: May 26th, 2020, 1:31 pm Technically, hiding and showing CPU #1 is a little redundant. You'll need a least 1 CPU core to actually do anything, for without at least 1 CPU, your computer will be an inert circuit board…
Agree. However the conditions have to cover this case as well. My opinion...
DavidRGreen wrote: May 26th, 2020, 1:31 pm "Styles" look interesting. I just haven't read all the documentation yet. I'll get there eventually.
It can shorten the code. In some cases extremely much...
DavidRGreen wrote: May 26th, 2020, 1:31 pm And BTW, SolidColor=0,0,0,1 is not "completely transparent", it is ¹/₂₅₅ opaque! :)
Technically it is not, indeed, however you won't see such a background with naked eyes, but it'll react to mouse clicks.
User avatar
DavidRGreen
Posts: 35
Joined: May 5th, 2020, 10:19 am

Re: Round 4 Core CPU Meter

Post by DavidRGreen »

I started putting in some of the code you (balala) suggested, and while it technically works, it does look a bit off in the log…

Code: Select all

[DetectCores]
Measure=Plugin
Plugin=RunCommand
Parameter=WMIC CPU Get NumberOfLogicalProcessors
State=Hide
OutputType=ANSI
RegExpSubstitute=1
Substitute="\n":"","\s":"",".*(\d{1,2})":"\1"
IfCondition=([#CURRENTSECTION#]=2)
IfTrueAction=[!ShowMeterGroup "Ring1"][!Log "Core 2"]
IfCondition2=([#CURRENTSECTION#]=4)
IfTrueAction2=[!ShowMeterGroup "Ring1"][!ShowMeterGroup "Ring2"][!Log "Core 4"]
IfCondition3=([#CURRENTSECTION#]=6)
IfTrueAction3=[!ShowMeterGroup "Ring1"][!ShowMeterGroup "Ring2"][!ShowMeterGroup "Ring3"][!Log "Core 6"]
IfCondition4=([#CURRENTSECTION#]=8)
IfTrueAction4=[!ShowMeterGroup "Ring1"][!ShowMeterGroup "Ring2"][!ShowMeterGroup "Ring3"][!ShowMeterGroup "Ring4"][!Log "Core 8"]
DynamicVariables=1
By adding Hidden =1 to each core, and I added a Group=Ringx to each Core pair, the number of Bangs required can be considerably reduced; one Bang per pair.

However, the log results do look a bit off;

Code: Select all

Notice:    Refreshing skin (RoundCPUMeter\RoundCPU8Meter.ini)
Warning:   CPU: Processor=5 is not valid (RoundCPUMeter\RoundCPU8Meter.ini - [MeasureCPU5])
… similarly for CPUs 6 through 8
Error:     Extra operation: IfCondition=(=2) (RoundCPUMeter\RoundCPU8Meter.ini - [DetectCores])
… similarly for the next 3 conditions
Notice:    Core 4 (RoundCPUMeter\RoundCPU8Meter.ini)
The warnings are obvious, the cores are not there, so they cannot be polled. Can a measure be turned off?

The errors in the log suggest that the section is completing before [#CURRENTSECTION#] is evaluated, and then the section is running again when [#CURRENTSECTION#] is evaluated and the message "Core 4" appears as it is attached to the true condition of the second test.

Rainmeter's core code probably has an internal reference to the number of cores. If this was available as an accessible system variable (like #CPUCORECOUNT#), the above logic would probably run smoother, without the need to call an external executable and fetch the result.

My first impression is that Core number detection process needs a wait status for the results from the external shell call to avoid the error conditions.
User avatar
balala
Rainmeter Sage
Posts: 16110
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Round 4 Core CPU Meter

Post by balala »

DavidRGreen wrote: May 30th, 2020, 10:21 am The warnings are obvious, the cores are not there, so they cannot be polled. Can a measure be turned off?
Not turned off, but disabled. Yes, it / they can be. Add a Disabled=1 option to all measures from [MeasureCPU2] to [MeasureCPU8] (supposing [MeasureCPU1] doesn't have to be disabled, because probably at least one core has to exist), then add a few bangs to the IfTrueActionXX options of the [MeasureRun] measure, to enable the appropriate CPU measures:

Code: Select all

[MeasureRun]
Measure=Plugin
Plugin=RunCommand
Parameter=WMIC CPU Get NumberOfLogicalProcessors
State=Hide
OutputType=ANSI
RegExpSubstitute=1
Substitute="\n":"","\s":"",".*(\d{1,2})":"\1"
IfCondition=([#CURRENTSECTION#]=1)
IfTrueAction=[!DisableMeasure "MeasureCPU2"][!DisableMeasure "MeasureCPU3"][!DisableMeasure "MeasureCPU4"][!DisableMeasure "MeasureCPU5"][!DisableMeasure "MeasureCPU6"][!DisableMeasure "MeasureCPU7"][!DisableMeasure "MeasureCPU8"][!ShowMeter "DisplayCPU1"][!HideMeter "DisplayCPU2"][!HideMeter "DisplayCPU3"][!HideMeter "DisplayCPU4"][!HideMeter "DisplayCPU5"][!HideMeter "DisplayCPU6"][!HideMeter "DisplayCPU7"][!HideMeter "DisplayCPU8"]
IfCondition2=([#CURRENTSECTION#]=2)
IfTrueAction2=[!EnableMeasure "MeasureCPU2"][!DisableMeasure "MeasureCPU3"][!DisableMeasure "MeasureCPU4"][!DisableMeasure "MeasureCPU5"][!DisableMeasure "MeasureCPU6"][!DisableMeasure "MeasureCPU7"][!DisableMeasure "MeasureCPU8"][!ShowMeter "DisplayCPU1"][!ShowMeter "DisplayCPU2"][!HideMeter "DisplayCPU3"][!HideMeter "DisplayCPU4"][!HideMeter "DisplayCPU5"][!HideMeter "DisplayCPU6"][!HideMeter "DisplayCPU7"][!HideMeter "DisplayCPU8"]
IfCondition3=([#CURRENTSECTION#]=4)
IfTrueAction3=[!EnableMeasure "MeasureCPU2"][!EnableMeasure "MeasureCPU3"][!EnableMeasure "MeasureCPU4"][!DisableMeasure "MeasureCPU5"][!DisableMeasure "MeasureCPU6"][!DisableMeasure "MeasureCPU7"][!DisableMeasure "MeasureCPU8"][!ShowMeter "DisplayCPU1"][!ShowMeter "DisplayCPU2"][!ShowMeter "DisplayCPU3"][!ShowMeter "DisplayCPU4"][!HideMeter "DisplayCPU5"][!HideMeter "DisplayCPU6"][!HideMeter "DisplayCPU7"][!HideMeter "DisplayCPU8"]
IfCondition4=([#CURRENTSECTION#]=6)
IfTrueAction4=[!EnableMeasure "MeasureCPU2"][!EnableMeasure "MeasureCPU3"][!EnableMeasure "MeasureCPU4"][!EnableMeasure "MeasureCPU5"][!EnableMeasure "MeasureCPU6"][!DisableMeasure "MeasureCPU7"][!DisableMeasure "MeasureCPU8"][!ShowMeter "DisplayCPU1"][!ShowMeter "DisplayCPU2"][!ShowMeter "DisplayCPU3"][!ShowMeter "DisplayCPU4"][!ShowMeter "DisplayCPU5"][!ShowMeter "DisplayCPU6"][!HideMeter "DisplayCPU7"][!HideMeter "DisplayCPU8"]
IfCondition5=([#CURRENTSECTION#]=8)
IfTrueAction5=[!EnableMeasure "MeasureCPU2"][!EnableMeasure "MeasureCPU3"][!EnableMeasure "MeasureCPU4"][!EnableMeasure "MeasureCPU5"][!EnableMeasure "MeasureCPU6"][!EnableMeasure "MeasureCPU7"][!EnableMeasure "MeasureCPU8"][!ShowMeter "DisplayCPU1"][!ShowMeter "DisplayCPU2"][!ShowMeter "DisplayCPU3"][!ShowMeter "DisplayCPU4"][!ShowMeter "DisplayCPU5"][!ShowMeter "DisplayCPU6"][!ShowMeter "DisplayCPU7"][!ShowMeter "DisplayCPU8"]
DynamicVariables=1