Skip to content

Commit

Permalink
[systeminfo] Update dependencies and add null annotations (openhab#5929)
Browse files Browse the repository at this point in the history
* [systeminfo] Update dependencies and add null annotations

* Update oshi to 4.0.0
* Update jna to 5.4.0
* Add null annotations

The cpu#load channel is removed because its data is no longer provided by oshi.
The load1, load5 and load15 channels can be used instead.
On the Oracle JVM this information can also be obtained using com.sun.management.OperatingSystemMXBean.getSystemCpuLoad()

See also:
* https://github.com/oshi/oshi/blob/master/UPGRADING.md
* https://github.com/oshi/oshi/blob/master/CHANGELOG.md#400-8102019

Fixes openhab#5921

Signed-off-by: Wouter Born <[email protected]>
Signed-off-by: Tim Roberts <[email protected]>
  • Loading branch information
wborn authored and tmrobert8 committed Jan 21, 2020
1 parent 1c8834c commit 645bbac
Show file tree
Hide file tree
Showing 13 changed files with 169 additions and 184 deletions.
7 changes: 2 additions & 5 deletions bundles/org.openhab.binding.systeminfo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
System information Binding provides operating system and hardware information including:

- Operating system name, version and manufacturer;
- CPU average recent load and 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;
- Free, total and available memory;
- Free, total and available swap memory;
- Hard drive name, model and serial number;
Expand Down Expand Up @@ -81,7 +81,7 @@ 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`
* **channel** `name, description, load1, load5, load15, uptime`
* **group** `sensors`
* **channel** `cpuTemp, cpuVoltage, fanSpeed`
* **group** `network` (deviceIndex)
Expand All @@ -108,7 +108,6 @@ The binding introduces the following channels:

| Channel ID | Channel Description | Supported item type | Default priority | Advanced |
|--------------------|------------------------------------------------------------------|---------------------|------------------|----------|
| load | Recent load in percents | Number | High | False |
| load1 | Load for the last 1 minute | Number | Medium | True |
| load5 | Load for the last 5 minutes | Number | Medium | True |
| load15 | Load for the last 15 minutes | Number | Medium | True |
Expand Down Expand Up @@ -207,7 +206,6 @@ Number Network_PacketsReceived "Packets received" <returnpipe> { chann
/* CPU information*/
String CPU_Name "Name" <none> { channel="systeminfo:computer:work:cpu#name" }
String CPU_Description "Description" <none> { channel="systeminfo:computer:work:cpu#description" }
Number CPU_Load "Load" <none> { channel="systeminfo:computer:work:cpu#load"}
Number CPU_Load1 "Load (1 min)" <none> { channel="systeminfo:computer:work:cpu#load1" }
Number CPU_Load5 "Load (5 min)" <none> { channel="systeminfo:computer:work:cpu#load5" }
Number CPU_Load15 "Load (15 min)" <none> { channel="systeminfo:computer:work:cpu#load15" }
Expand Down Expand Up @@ -281,7 +279,6 @@ Text label="Systeminfo" {
Frame label="CPU Information" {
Default item=CPU_Name
Default item=CPU_Description
Default item=CPU_Load
Default item=CPU_Load1
Default item=CPU_Load5
Default item=CPU_Load15
Expand Down
6 changes: 3 additions & 3 deletions bundles/org.openhab.binding.systeminfo/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.3.0</version>
<version>5.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.3.0</version>
<version>5.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>3.13.0</version>
<version>4.0.0</version>
<scope>provided</scope>
<exclusions>
<exclusion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

<feature name="openhab-binding-systeminfo" description="System Info Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle dependency="true">mvn:net.java.dev.jna/jna/5.3.0</bundle>
<bundle dependency="true">mvn:net.java.dev.jna/jna-platform/5.3.0</bundle>
<bundle dependency="true">mvn:com.github.oshi/oshi-core/3.13.0</bundle>
<bundle dependency="true">mvn:net.java.dev.jna/jna/5.4.0</bundle>
<bundle dependency="true">mvn:net.java.dev.jna/jna-platform/5.4.0</bundle>
<bundle dependency="true">mvn:com.github.oshi/oshi-core/4.0.0</bundle>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.systeminfo/${project.version}</bundle>
</feature>
</features>
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import java.util.Collections;
import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.ThingTypeUID;
import org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory;
Expand All @@ -33,21 +35,23 @@
*
* @author Svilen Valkanov - Initial contribution
* @author Lyubomir Papazov - Pass systeminfo service to the SysteminfoHandler constructor
* @author Wouter Born - Add null annotations
*/
@NonNullByDefault
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.systeminfo")
public class SysteminfoHandlerFactory extends BaseThingHandlerFactory {

private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_TYPE_COMPUTER);

private SysteminfoInterface systeminfo;
private @NonNullByDefault({}) SysteminfoInterface systeminfo;

@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
}

@Override
protected ThingHandler createHandler(Thing thing) {
protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();

if (thingTypeUID.equals(THING_TYPE_COMPUTER)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Collections;
import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.smarthome.config.discovery.AbstractDiscoveryService;
import org.eclipse.smarthome.config.discovery.DiscoveryResult;
import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder;
Expand All @@ -35,7 +36,9 @@
* {@link #DEFAULT_THING_LABEL}. The discovered Thing will have id - the hostname or {@link #DEFAULT_THING_ID}'
*
* @author Svilen Valkanov - Initial contribution
* @author Wouter Born - Add null annotations
*/
@NonNullByDefault
@Component(service = DiscoveryService.class, immediate = true, configurationPid = "discovery.systeminfo")
public class SysteminfoDiscoveryService extends AbstractDiscoveryService {
public static final String DEFAULT_THING_ID = "unknown";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.config.core.Configuration;
import org.eclipse.smarthome.core.thing.Channel;
import org.eclipse.smarthome.core.thing.ChannelUID;
Expand All @@ -46,39 +47,40 @@
*
* @author Svilen Valkanov - Initial contribution
* @author Lyubomir Papzov - Separate the creation of the systeminfo object and its initialization
* @author Wouter Born - Add null annotations
*/

@NonNullByDefault
public class SysteminfoHandler extends BaseThingHandler {
/**
* Refresh interval for {@link #highPriorityChannels} in seconds.
*/
private BigDecimal refreshIntervalHighPriority;
private @NonNullByDefault({}) BigDecimal refreshIntervalHighPriority;

/**
* Refresh interval for {@link #mediumPriorityChannels} in seconds.
*/
private BigDecimal refreshIntervalMediumPriority;
private @NonNullByDefault({}) BigDecimal refreshIntervalMediumPriority;

/**
* Channels with priority configuration parameter set to High. They usually need frequent update of the state like
* CPU load, or information about the free and used memory.
* They are updated periodically at {@link #refreshIntervalHighPriority}.
*/
private Set<ChannelUID> highPriorityChannels = new HashSet<>();
private final Set<ChannelUID> highPriorityChannels = new HashSet<>();

/**
* Channels with priority configuration parameter set to Medium. These channels usually need update of the
* state not so oft like battery capacity, storage used and etc.
* They are updated periodically at {@link #refreshIntervalMediumPriority}.
*/
private Set<ChannelUID> mediumPriorityChannels = new HashSet<>();
private final Set<ChannelUID> mediumPriorityChannels = new HashSet<>();

/**
* Channels with priority configuration parameter set to Low. They represent static information or information
* that is updated rare- e.g. CPU name, storage name and etc.
* They are updated only at {@link #initialize()}.
*/
private Set<ChannelUID> lowPriorityChannels = new HashSet<>();
private final Set<ChannelUID> lowPriorityChannels = new HashSet<>();

/**
* Wait time for the creation of Item-Channel links in seconds. This delay is needed, because the Item-Channel
Expand All @@ -88,12 +90,12 @@ public class SysteminfoHandler extends BaseThingHandler {

private SysteminfoInterface systeminfo;

ScheduledFuture<?> highPriorityTasks;
ScheduledFuture<?> mediumPriorityTasks;
private @Nullable ScheduledFuture<?> highPriorityTasks;
private @Nullable ScheduledFuture<?> mediumPriorityTasks;

private Logger logger = LoggerFactory.getLogger(SysteminfoHandler.class);

public SysteminfoHandler(@NonNull Thing thing, SysteminfoInterface systeminfo) {
public SysteminfoHandler(Thing thing, @Nullable SysteminfoInterface systeminfo) {
super(thing);
if (systeminfo != null) {
this.systeminfo = systeminfo;
Expand Down Expand Up @@ -238,26 +240,19 @@ private void scheduleUpdates() {
}

private void publishData(Set<ChannelUID> channels) {
if (channels != null) {
Iterator<ChannelUID> iter = channels.iterator();
while (iter.hasNext()) {
ChannelUID channeUID = iter.next();
if (isLinked(channeUID.getId())) {
publishDataForChannel(channeUID);
}
Iterator<ChannelUID> iter = channels.iterator();
while (iter.hasNext()) {
ChannelUID channeUID = iter.next();
if (isLinked(channeUID.getId())) {
publishDataForChannel(channeUID);
}
}
}

private void publishDataForChannel(ChannelUID channelUID) {
State state = getInfoForChannel(channelUID);
String channelID = channelUID.getId();
if (state != null) {
updateState(channelID, state);
} else {
logger.warn("Channel with ID {} cannot be updated! No information available for the selected device.",
channelID);
}
updateState(channelID, state);
}

public Set<ChannelUID> getHighPriorityChannels() {
Expand All @@ -282,6 +277,7 @@ public Set<ChannelUID> getLowPriorityChannels() {
*/
private State getInfoForChannel(ChannelUID channelUID) {
State state = null;

String channelID = channelUID.getId();
String channelIDWithoutGroup = channelUID.getIdWithoutGroup();
String channelGroupID = channelUID.getGroupId();
Expand All @@ -291,7 +287,9 @@ private State getInfoForChannel(ChannelUID channelUID) {
// The channelGroup may contain deviceIndex. It must be deleted from the channelID, because otherwise the
// switch will not find the correct method below.
// All digits are deleted from the ID
channelID = channelGroupID.replaceAll("\\d+", "") + "#" + channelIDWithoutGroup;
if (channelGroupID != null) {
channelID = channelGroupID.replaceAll("\\d+", "") + "#" + channelIDWithoutGroup;
}

try {
switch (channelID) {
Expand All @@ -316,9 +314,6 @@ private State getInfoForChannel(ChannelUID channelUID) {
case CHANNEL_SENSORS_FAN_SPEED:
state = systeminfo.getSensorsFanSpeed(deviceIndex);
break;
case CHANNEL_CPU_LOAD:
state = systeminfo.getCpuLoad();
break;
case CHANNEL_CPU_LOAD_1:
state = systeminfo.getCpuLoad1();
break;
Expand Down Expand Up @@ -465,22 +460,26 @@ private State getInfoForChannel(ChannelUID channelUID) {
* @return natural number (number >=0)
*/
private int getDeviceIndex(ChannelUID channelUID) {
int deviceIndex = 0;
if (channelUID.getGroupId().contains(CHANNEL_GROUP_PROCESS)) {
String channelGroupID = channelUID.getGroupId();
if (channelGroupID == null) {
return 0;
}

if (channelGroupID.contains(CHANNEL_GROUP_PROCESS)) {
// Only in this case the deviceIndex is part of the channel configuration - PID (Process Identifier)
int pid = getPID(channelUID);
deviceIndex = pid;
logger.debug("Channel with UID {} tracks process with PID: {}", channelUID, pid);
} else {
String channelGroupID = channelUID.getGroupId();
char lastChar = channelGroupID.charAt(channelGroupID.length() - 1);
if (Character.isDigit(lastChar)) {
// All non-digits are deleted from the ID
String deviceIndexPart = channelGroupID.replaceAll("\\D+", "");
deviceIndex = Integer.parseInt(deviceIndexPart);
}
return pid;
}

char lastChar = channelGroupID.charAt(channelGroupID.length() - 1);
if (Character.isDigit(lastChar)) {
// All non-digits are deleted from the ID
String deviceIndexPart = channelGroupID.replaceAll("\\D+", "");
return Integer.parseInt(deviceIndexPart);
}
return deviceIndex;

return 0;
}

/**
Expand All @@ -492,14 +491,18 @@ private int getDeviceIndex(ChannelUID channelUID) {
private int getPID(ChannelUID channelUID) {
int pid = 0;
try {
Configuration channelProperties = this.thing.getChannel(channelUID.getId()).getConfiguration();
BigDecimal pidValue = (BigDecimal) channelProperties.get(PID_PARAM);
if (pidValue == null || pidValue.intValue() < 0) {
throw new IllegalArgumentException("Invalid value for Process Identifier.");
Channel channel = this.thing.getChannel(channelUID.getId());
if (channel != null) {
Configuration channelProperties = channel.getConfiguration();
BigDecimal pidValue = (BigDecimal) channelProperties.get(PID_PARAM);
if (pidValue == null || pidValue.intValue() < 0) {
throw new IllegalArgumentException("Invalid value for Process Identifier.");
} else {
pid = pidValue.intValue();
}
} else {
pid = pidValue.intValue();
logger.debug("Channel does not exist ! Fall back to default value.");
}

} catch (ClassCastException e) {
logger.debug("Channel configuration cannot be read ! Fall back to default value.", e);
} catch (IllegalArgumentException e) {
Expand All @@ -523,17 +526,14 @@ public void handleCommand(ChannelUID channelUID, Command command) {
}

private boolean isConfigurationKeyChanged(Configuration currentConfig, Configuration newConfig, String key) {
if (currentConfig != null && newConfig != null) {
Object currentValue = currentConfig.get(key);
Object newValue = newConfig.get(key);

if (currentValue == null) {
return (newValue != null);
}
Object currentValue = currentConfig.get(key);
Object newValue = newConfig.get(key);

return !currentValue.equals(newValue);
if (currentValue == null) {
return (newValue != null);
}
return true;

return !currentValue.equals(newValue);
}

@Override
Expand Down Expand Up @@ -586,13 +586,16 @@ private void handleChannelConfigurationChange(Channel channel, Configuration new
}

private void stopScheduledUpdates() {
if (highPriorityTasks != null) {
ScheduledFuture<?> localHighPriorityTasks = highPriorityTasks;
if (localHighPriorityTasks != null) {
logger.debug("High prioriy tasks will not be run anymore !");
highPriorityTasks.cancel(true);
localHighPriorityTasks.cancel(true);
}
if (mediumPriorityTasks != null) {

ScheduledFuture<?> localMediumPriorityTasks = mediumPriorityTasks;
if (localMediumPriorityTasks != null) {
logger.debug("Medium prioriy tasks will not be run anymore !");
mediumPriorityTasks.cancel(true);
localMediumPriorityTasks.cancel(true);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@

import java.io.IOException;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* {@link DeviceNotFoundException} is used to indicate that device can not be found on this hardware configuration, most
* probably because the device is not installed.
*
* @author Svilen Valkanov - Initial contribution
* @author Wouter Born - Add null annotations
*/
@NonNullByDefault
public class DeviceNotFoundException extends IOException {
private static final long serialVersionUID = -707507777792259512L;

Expand Down
Loading

0 comments on commit 645bbac

Please sign in to comment.