From d8f4887ea512ac1876f77d24a2399e8ef81628ae Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Mon, 18 Mar 2024 11:58:54 +0100 Subject: [PATCH] [systeminfo] Add CPU frequency channels (#16012) Signed-off-by: Mark Herwege Signed-off-by: Ciprian Pascu --- .../org.openhab.binding.systeminfo/README.md | 25 ++++++--- .../internal/SysteminfoBindingConstants.java | 11 ++++ .../internal/SysteminfoThingTypeProvider.java | 5 ++ .../internal/handler/SysteminfoHandler.java | 8 +++ .../internal/model/OSHISysteminfo.java | 14 +++++ .../internal/model/SysteminfoInterface.java | 14 +++++ .../main/resources/OH-INF/thing/channels.xml | 18 ++++++ .../main/resources/OH-INF/thing/computer.xml | 2 + .../main/resources/OH-INF/update/update.xml | 17 ++++++ .../pom.xml | 2 +- .../systeminfo/test/SysteminfoOSGiTest.java | 56 ++++++++++++++----- 11 files changed, 148 insertions(+), 24 deletions(-) create mode 100644 bundles/org.openhab.binding.systeminfo/src/main/resources/OH-INF/update/update.xml diff --git a/bundles/org.openhab.binding.systeminfo/README.md b/bundles/org.openhab.binding.systeminfo/README.md index 43754d94637..2e2921a69b5 100644 --- a/bundles/org.openhab.binding.systeminfo/README.md +++ b/bundles/org.openhab.binding.systeminfo/README.md @@ -3,7 +3,7 @@ The system information binding provides operating system and hardware information including: - Operating system name, version and manufacturer; -- CPU average load for last 1, 5, 15 minutes, name, description, number of physical and logical cores, running threads number, system uptime; +- CPU average load for last 1, 5, 15 minutes, name, description, number of physical and logical cores, running threads number, system uptime, max frequency and frequency by logical core; - Free, total and available memory; - Free, total and available swap memory; - Hard drive name, model and serial number; @@ -76,9 +76,9 @@ In the list below, you can find, how are channel group and channels id`s related - **group** `battery` (deviceIndex) - **channel** `name, remainingCapacity, remainingTime` - **group** `cpu` - - **channel** `name, description, load, load1, load5, load15, uptime, threads` + - **channel** `name, description, maxfreq, freq `(deviceIndex)`, load, load1, load5, load15, uptime, threads` - **group** `sensors` - - **channel** `cpuTemp, cpuVoltage, fanSpeed` + - **channel** `cpuTemp, cpuVoltage, fanSpeed `(deviceIndex) - **group** `network` (deviceIndex) - **channel** `ip, mac, networkDisplayName, networkName, packetsSent, packetsReceived, dataSent, dataReceived` - **group** `currentProcess` @@ -92,7 +92,7 @@ The groups marked with "(deviceIndex)" may have device index attached to the Cha - deviceIndex ::= number >= 0 - (e.g. _storage1#available_) -The `fanSpeed` channel in the `sensors` group may have a device index attached to the Channel. +The channels marked with "(deviceIndex)" may have a device index attached to the Channel. - channel ::= channel_group & # channel_id & (deviceIndex) - deviceIndex ::= number >= 0 @@ -119,6 +119,8 @@ The binding introduces the following channels: | load5 | Load for the last 5 minutes | Number | Medium | True | | load15 | Load for the last 15 minutes | Number | Medium | True | | threads | Number of threads currently running or for the process | Number | Medium | True | +| maxfreq | CPU maximum frequency | Number:Frequency | Low | True | +| freq | Logical processor frequency | Number:Frequency | High | True | | path | The full path of the process | String | Low | False | | uptime | System uptime (time after start) in minutes | Number:Time | Medium | True | | name | Name of the device or process | String | Low | False | @@ -172,6 +174,7 @@ Parameter PID has a default value 0 - this is the PID of the System Idle process ## Known issues and workarounds - Temperature readings are not well supported on standard Windows systems, run [OpenHardwareMonitor.exe](https://openhardwaremonitor.org) for the binding to get more reliable readings. +- CPU frequency readings are not available on some OS versions. ## Reporting issues @@ -179,9 +182,9 @@ As already mentioned this binding depends heavily on the [OSHI](https://github.c Take a look at the console for an ERROR log message. -If you find an issue with a support for a specific hardware or software architecture please take a look at the [OSHI issues](https://github.com/oshi/oshi/issues). +If you find an issue with support for a specific hardware or software architecture please take a look at the [OSHI issues](https://github.com/oshi/oshi/issues). Your problem might have be already reported and solved! -Feel free to open a new issue there with the log message and the and information about your software or hardware configuration. +Feel free to open a new issue there with the log message and the information about your software or hardware configuration. For a general problem with the binding report the issue directly to openHAB. @@ -209,6 +212,8 @@ Number Network_PacketsReceived "Packets received" { chann /* CPU information*/ String CPU_Name "Name" { channel="systeminfo:computer:work:cpu#name" } String CPU_Description "Description" { channel="systeminfo:computer:work:cpu#description" } +Number:Frequency CPU_MaxFreq "CPU Max Frequency" { channel="systeminfo:computer:work:cpu#maxfreq" } +Number:Frequency CPU_Freq "CPU Frequency" { channel="systeminfo:computer:work:cpu#freq" } Number:Dimensionless CPU_Load "CPU Load" { channel="systeminfo:computer:work:cpu#load" } Number CPU_Load1 "Load (1 min)" { channel="systeminfo:computer:work:cpu#load1" } Number CPU_Load5 "Load (5 min)" { channel="systeminfo:computer:work:cpu#load5" } @@ -232,7 +237,7 @@ Number:Dimensionless Storage_Available_Percent "Available (%)" { chann Number:Dimensionless Storage_Used_Percent "Used (%)" { channel="systeminfo:computer:work:storage#usedPercent" } /* Memory information*/ -Number Memory_Available "Available" { channel="systeminfo:computer:work:memory#available" } +Number:DataAmount Memory_Available "Available" { channel="systeminfo:computer:work:memory#available" } Number:DataAmount Memory_Used "Used" { channel="systeminfo:computer:work:memory#used" } Number:DataAmount Memory_Total "Total" { channel="systeminfo:computer:work:memory#total" } Number:Dimensionless Memory_Available_Percent "Available (%)" { channel="systeminfo:computer:work:memory#availablePercent" } @@ -260,14 +265,14 @@ Number Sensor_FanSpeed "Fan speed" { chann /* Current process information*/ Number:Dimensionless Current_process_load "Load" { channel="systeminfo:computer:work:currentProcess#load" } -Number:Dimensionless Current_process_used "Used" { channel="systeminfo:computer:work:currentProcess#used" } +Number:DataAmount Current_process_used "Used" { channel="systeminfo:computer:work:currentProcess#used" } String Current_process_name "Name" { channel="systeminfo:computer:work:currentProcess#name" } Number Current_process_threads "Threads" { channel="systeminfo:computer:work:currentProcess#threads" } String Current_process_path "Path" { channel="systeminfo:computer:work:currentProcess#path" } /* Process information*/ Number:Dimensionless Process_load "Load" { channel="systeminfo:computer:work:process#load" } -Number:Dimensionless Process_used "Used" { channel="systeminfo:computer:work:process#used" } +Number:DataAmount Process_used "Used" { channel="systeminfo:computer:work:process#used" } String Process_name "Name" { channel="systeminfo:computer:work:process#name" } Number Process_threads "Threads" { channel="systeminfo:computer:work:process#threads" } String Process_path "Path" { channel="systeminfo:computer:work:process#path" } @@ -290,6 +295,8 @@ sitemap systeminfo label="Systeminfo" { Frame label="CPU Information" { Default item=CPU_Name Default item=CPU_Description + Default item=CPU_MaxFreq + Default item=CPU_Freq Default item=CPU_Load1 Default item=CPU_Load5 Default item=CPU_Load15 diff --git a/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/SysteminfoBindingConstants.java b/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/SysteminfoBindingConstants.java index 67d328fc4fa..ebe6c7ac83d 100644 --- a/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/SysteminfoBindingConstants.java +++ b/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/SysteminfoBindingConstants.java @@ -21,6 +21,7 @@ import org.openhab.core.thing.ThingTypeUID; * * @author Svilen Valkanov - Initial contribution * @author Mark Herwege - Add dynamic creation of extra channels + * @author Mark Herwege - Processor frequency channels */ @NonNullByDefault public class SysteminfoBindingConstants { @@ -278,6 +279,16 @@ public class SysteminfoBindingConstants { */ public static final String CHANNEL_CPU_DESCRIPTION = "cpu#description"; + /** + * Maximum frequency of the CPU + */ + public static final String CHANNEL_CPU_MAXFREQ = "cpu#maxfreq"; + + /** + * Frequency of the CPU + */ + public static final String CHANNEL_CPU_FREQ = "cpu#freq"; + /** * Average recent CPU load */ diff --git a/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/SysteminfoThingTypeProvider.java b/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/SysteminfoThingTypeProvider.java index e54806436c2..20ab103161b 100644 --- a/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/SysteminfoThingTypeProvider.java +++ b/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/SysteminfoThingTypeProvider.java @@ -230,10 +230,15 @@ public class SysteminfoThingTypeProvider extends AbstractStorageBasedTypeProvide ChannelBuilder builder = ChannelBuilder.create(channelUID).withType(channelTypeUID) .withConfiguration(baseChannel.getConfiguration()); builder.withLabel(channelType.getLabel() + " " + index); + builder.withDefaultTags(channelType.getTags()); String description = channelType.getDescription(); if (description != null) { builder.withDescription(description); } + String itemType = channelType.getItemType(); + if (itemType != null) { + builder.withAcceptedItemType(itemType); + } return builder.build(); } diff --git a/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/handler/SysteminfoHandler.java b/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/handler/SysteminfoHandler.java index bdd27979fb3..3454ee999fe 100644 --- a/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/handler/SysteminfoHandler.java +++ b/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/handler/SysteminfoHandler.java @@ -63,6 +63,7 @@ import org.slf4j.LoggerFactory; * @author Lyubomir Papzov - Separate the creation of the systeminfo object and its initialization * @author Wouter Born - Add null annotations * @author Mark Herwege - Add dynamic creation of extra channels + * @author Mark Herwege - Processor frequency channels */ @NonNullByDefault public class SysteminfoHandler extends BaseThingHandler { @@ -258,6 +259,7 @@ public class SysteminfoHandler extends BaseThingHandler { List newChannels = new ArrayList<>(); newChannels.addAll(createChannels(thingUID, CHANNEL_SENSORS_FAN_SPEED, systeminfo.getFanCount())); + newChannels.addAll(createChannels(thingUID, CHANNEL_CPU_FREQ, systeminfo.getCpuLogicalCores().intValue())); if (!newChannels.isEmpty()) { logger.debug("Creating additional channels"); newChannels.addAll(0, thing.getChannels()); @@ -482,6 +484,12 @@ public class SysteminfoHandler extends BaseThingHandler { case CHANNEL_SENSORS_FAN_SPEED: state = systeminfo.getSensorsFanSpeed(deviceIndex); break; + case CHANNEL_CPU_MAXFREQ: + state = systeminfo.getCpuMaxFreq(); + break; + case CHANNEL_CPU_FREQ: + state = systeminfo.getCpuFreq(deviceIndex); + break; case CHANNEL_CPU_LOAD: PercentType cpuLoad = cpuLoadCache.getValue(); state = (cpuLoad != null) ? new QuantityType<>(cpuLoad, Units.PERCENT) : null; diff --git a/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/model/OSHISysteminfo.java b/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/model/OSHISysteminfo.java index da186971fa6..2277d59e26c 100644 --- a/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/model/OSHISysteminfo.java +++ b/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/model/OSHISysteminfo.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Map; import javax.measure.quantity.ElectricPotential; +import javax.measure.quantity.Frequency; import javax.measure.quantity.Temperature; import javax.measure.quantity.Time; @@ -62,6 +63,7 @@ import oshi.util.EdidUtil; * @author Wouter Born - Update to OSHI 4.0.0 and add null annotations * @author Mark Herwege - Add dynamic creation of extra channels * @author Mark Herwege - Use units of measure + * @author Mark Herwege - Processor frequency channels * * @see OSHI GitHub repository */ @@ -197,6 +199,18 @@ public class OSHISysteminfo implements SysteminfoInterface { return new DecimalType(physicalProcessorCount); } + @Override + public @Nullable QuantityType getCpuMaxFreq() { + long maxFreq = cpu.getMaxFreq(); + return maxFreq >= 0 ? new QuantityType<>(maxFreq, Units.HERTZ) : null; + } + + @Override + public @Nullable QuantityType getCpuFreq(int logicalProcessorIndex) { + long freq = cpu.getCurrentFreq()[logicalProcessorIndex]; + return freq >= 0 ? new QuantityType<>(freq, Units.HERTZ) : null; + } + @Override public QuantityType getMemoryTotal() { long totalMemory = memory.getTotal(); diff --git a/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/model/SysteminfoInterface.java b/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/model/SysteminfoInterface.java index 819df7cfbdd..8873ee3243e 100644 --- a/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/model/SysteminfoInterface.java +++ b/bundles/org.openhab.binding.systeminfo/src/main/java/org/openhab/binding/systeminfo/internal/model/SysteminfoInterface.java @@ -13,6 +13,7 @@ package org.openhab.binding.systeminfo.internal.model; import javax.measure.quantity.ElectricPotential; +import javax.measure.quantity.Frequency; import javax.measure.quantity.Temperature; import javax.measure.quantity.Time; @@ -31,6 +32,7 @@ import org.openhab.core.library.types.StringType; * @author Wouter Born - Add null annotations * @author Mark Herwege - Add dynamic creation of extra channels * @author Mark Herwege - Use units of measure + * @author Mark Herwege - Processor frequency channels */ @NonNullByDefault public interface SysteminfoInterface { @@ -80,6 +82,18 @@ public interface SysteminfoInterface { */ DecimalType getCpuPhysicalCores(); + /** + * Get the maximum CPU frequency of the processor. + */ + @Nullable + QuantityType getCpuMaxFreq(); + + /** + * Get the current CPU frequency of a logical processor. + */ + @Nullable + QuantityType getCpuFreq(int logicalProcessorIndex); + /** * Returns the system cpu load. * diff --git a/bundles/org.openhab.binding.systeminfo/src/main/resources/OH-INF/thing/channels.xml b/bundles/org.openhab.binding.systeminfo/src/main/resources/OH-INF/thing/channels.xml index 193a734d0d4..51d58e338de 100644 --- a/bundles/org.openhab.binding.systeminfo/src/main/resources/OH-INF/thing/channels.xml +++ b/bundles/org.openhab.binding.systeminfo/src/main/resources/OH-INF/thing/channels.xml @@ -107,6 +107,8 @@ + + @@ -308,6 +310,22 @@ + + Number:Frequency + + CPU maximum frequency + + + + + + Number:Frequency + + Logical processor frequency + + + + Number:Dimensionless diff --git a/bundles/org.openhab.binding.systeminfo/src/main/resources/OH-INF/thing/computer.xml b/bundles/org.openhab.binding.systeminfo/src/main/resources/OH-INF/thing/computer.xml index 31c543de77c..3ebafc35a7f 100644 --- a/bundles/org.openhab.binding.systeminfo/src/main/resources/OH-INF/thing/computer.xml +++ b/bundles/org.openhab.binding.systeminfo/src/main/resources/OH-INF/thing/computer.xml @@ -26,6 +26,8 @@ + 1 + Not available Not available Not available diff --git a/bundles/org.openhab.binding.systeminfo/src/main/resources/OH-INF/update/update.xml b/bundles/org.openhab.binding.systeminfo/src/main/resources/OH-INF/update/update.xml new file mode 100644 index 00000000000..cd2e148fd47 --- /dev/null +++ b/bundles/org.openhab.binding.systeminfo/src/main/resources/OH-INF/update/update.xml @@ -0,0 +1,17 @@ + + + + + + + systeminfo:maxfreq + + + systeminfo:freq + + + + + diff --git a/itests/org.openhab.binding.systeminfo.tests/pom.xml b/itests/org.openhab.binding.systeminfo.tests/pom.xml index a4e9cabdbee..6ac85988a25 100644 --- a/itests/org.openhab.binding.systeminfo.tests/pom.xml +++ b/itests/org.openhab.binding.systeminfo.tests/pom.xml @@ -33,7 +33,7 @@ com.github.oshi oshi-core - 6.2.2 + 6.4.8 org.slf4j diff --git a/itests/org.openhab.binding.systeminfo.tests/src/main/java/org/openhab/binding/systeminfo/test/SysteminfoOSGiTest.java b/itests/org.openhab.binding.systeminfo.tests/src/main/java/org/openhab/binding/systeminfo/test/SysteminfoOSGiTest.java index 4025c3150e9..0c8394732d3 100644 --- a/itests/org.openhab.binding.systeminfo.tests/src/main/java/org/openhab/binding/systeminfo/test/SysteminfoOSGiTest.java +++ b/itests/org.openhab.binding.systeminfo.tests/src/main/java/org/openhab/binding/systeminfo/test/SysteminfoOSGiTest.java @@ -13,7 +13,6 @@ package org.openhab.binding.systeminfo.test; import static java.lang.Thread.sleep; -import static java.util.stream.Collectors.toList; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -23,8 +22,10 @@ import java.math.BigDecimal; import java.net.UnknownHostException; import java.util.Hashtable; import java.util.List; +import java.util.Map; import javax.measure.quantity.ElectricPotential; +import javax.measure.quantity.Frequency; import javax.measure.quantity.Temperature; import javax.measure.quantity.Time; @@ -93,11 +94,13 @@ import org.openhab.core.types.UnDefType; * @author Lyubomir Papazov - Created a mock systeminfo object. This way, access to the user's OS will not be required, * but mock data will be used instead, avoiding potential errors from the OS queries. * @author Wouter Born - Migrate Groovy to Java tests + * @author Mark Herwege - Processor frequency channels */ @NonNullByDefault @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) public class SysteminfoOSGiTest extends JavaOSGiTest { + private static final String DEFAULT_TEST_THING_NAME = "work"; private static final String DEFAULT_TEST_ITEM_NAME = "test"; private static final String DEFAULT_CHANNEL_TEST_PRIORITY = "High"; @@ -126,16 +129,17 @@ public class SysteminfoOSGiTest extends JavaOSGiTest { private @NonNullByDefault({}) ManagedThingProvider managedThingProvider; private @NonNullByDefault({}) ManagedItemChannelLinkProvider itemChannelLinkProvider; private @NonNullByDefault({}) UnitProvider unitProvider; + private @NonNullByDefault({}) VolatileStorageService volatileStorageService; @BeforeEach public void setUp() { - VolatileStorageService volatileStorageService = new VolatileStorageService(); + volatileStorageService = new VolatileStorageService(); registerService(volatileStorageService); // Preparing the mock with OS properties, that are used in the initialize method of SysteminfoHandler // Make this lenient because the assertInvalidThingConfigurationValuesAreHandled test does not require them - lenient().when(mockedSystemInfo.getCpuLogicalCores()).thenReturn(new DecimalType(2)); - lenient().when(mockedSystemInfo.getCpuPhysicalCores()).thenReturn(new DecimalType(2)); + lenient().when(mockedSystemInfo.getCpuLogicalCores()).thenReturn(new DecimalType(1)); + lenient().when(mockedSystemInfo.getCpuPhysicalCores()).thenReturn(new DecimalType(1)); lenient().when(mockedSystemInfo.getOsFamily()).thenReturn(new StringType("Mock OS")); lenient().when(mockedSystemInfo.getOsManufacturer()).thenReturn(new StringType("Mock OS Manufacturer")); lenient().when(mockedSystemInfo.getOsVersion()).thenReturn(new StringType("Mock Os Version")); @@ -164,11 +168,6 @@ public class SysteminfoOSGiTest extends JavaOSGiTest { systeminfoHandlerFactory.bindSystemInfo(mockedSystemInfo); } - waitForAssert(() -> { - systeminfoHandlerFactory = getService(ThingHandlerFactory.class, SysteminfoHandlerFactory.class); - assertThat(systeminfoHandlerFactory, is(notNullValue())); - }); - waitForAssert(() -> { thingRegistry = getService(ThingRegistry.class); assertThat(thingRegistry, is(notNullValue())); @@ -199,13 +198,14 @@ public class SysteminfoOSGiTest extends JavaOSGiTest { public void tearDown() { Thing thing = systeminfoThing; if (thing != null) { - // Remove the systeminfo thing. The handler will be also disposed automatically + // Remove the systeminfo thing. The handler will also be disposed automatically Thing removedThing = thingRegistry.forceRemove(thing.getUID()); assertThat("The systeminfo thing cannot be deleted", removedThing, is(notNullValue())); waitForAssert(() -> { ThingHandler systemInfoHandler = thing.getHandler(); assertThat(systemInfoHandler, is(nullValue())); }); + managedThingProvider.remove(thing.getUID()); } if (testItem != null) { @@ -213,6 +213,7 @@ public class SysteminfoOSGiTest extends JavaOSGiTest { } unregisterService(mockedSystemInfo); + unregisterService(volatileStorageService); } private void initializeThingWithChannelAndPID(String channelID, String acceptedItemType, int pid) { @@ -275,8 +276,12 @@ public class SysteminfoOSGiTest extends JavaOSGiTest { Channel channel = ChannelBuilder.create(channelUID, acceptedItemType).withType(channelTypeUID) .withKind(ChannelKind.STATE).withConfiguration(channelConfig).build(); - Thing thing = ThingBuilder.create(thingTypeUID, thingUID).withConfiguration(thingConfiguration) - .withChannel(channel).build(); + ThingBuilder thingBuilder = ThingBuilder.create(thingTypeUID, thingUID).withConfiguration(thingConfiguration) + .withChannel(channel); + // Make sure the thingTypeVersion matches the highest version in the update instructions of the binding to avoid + // new channels being added and the thing not initializing + thingBuilder = thingBuilder.withProperties(Map.of("thingTypeVersion", "1")); + Thing thing = thingBuilder.build(); systeminfoThing = thing; managedThingProvider.add(thing); @@ -399,6 +404,30 @@ public class SysteminfoOSGiTest extends JavaOSGiTest { assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, UnDefType.UNDEF); } + @Test + public void assertChannelCpuMaxFreq() { + String channnelID = SysteminfoBindingConstants.CHANNEL_CPU_MAXFREQ; + String acceptedItemType = "Number:Frequency"; + + QuantityType mockedCpuMaxFreqValue = new QuantityType<>(2500, Units.HERTZ); + when(mockedSystemInfo.getCpuMaxFreq()).thenReturn(mockedCpuMaxFreqValue); + + initializeThingWithChannel(channnelID, acceptedItemType); + assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedCpuMaxFreqValue); + } + + @Test + public void assertChannelCpuFreq() { + String channnelID = SysteminfoBindingConstants.CHANNEL_CPU_FREQ; + String acceptedItemType = "Number:Frequency"; + + QuantityType mockedCpuFreqValue = new QuantityType<>(2500, Units.HERTZ); + when(mockedSystemInfo.getCpuFreq(0)).thenReturn(mockedCpuFreqValue); + + initializeThingWithChannel(channnelID, acceptedItemType); + assertItemState(acceptedItemType, DEFAULT_TEST_ITEM_NAME, DEFAULT_CHANNEL_TEST_PRIORITY, mockedCpuFreqValue); + } + @Test public void assertChannelCpuLoadIsUpdated() { String channnelID = SysteminfoBindingConstants.CHANNEL_CPU_LOAD; @@ -997,8 +1026,7 @@ public class SysteminfoOSGiTest extends JavaOSGiTest { } waitForAssert(() -> { - List results = inbox.stream().filter(InboxPredicates.forThingUID(computerUID)) - .collect(toList()); + List results = inbox.stream().filter(InboxPredicates.forThingUID(computerUID)).toList(); assertFalse(results.isEmpty(), "No Thing with UID " + computerUID.getAsString() + " in inbox"); });