added migrated 2.x add-ons

Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
Kai Kreuzer
2020-09-21 01:58:32 +02:00
parent bbf1a7fd29
commit 6df6783b60
11662 changed files with 1302875 additions and 11 deletions

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.systeminfo-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
<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.5.0</bundle>
<bundle dependency="true">mvn:net.java.dev.jna/jna-platform/5.5.0</bundle>
<bundle dependency="true">mvn:com.github.oshi/oshi-core/4.5.2</bundle>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.systeminfo/${project.version}</bundle>
</feature>
</features>

View File

@@ -0,0 +1,333 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.systeminfo.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;
/**
* The {@link SysteminfoBindingConstants} class defines common constants, which are
* used across the whole binding.
*
* @author Svilen Valkanov - Initial contribution
*/
@NonNullByDefault
public class SysteminfoBindingConstants {
public static final String BINDING_ID = "systeminfo";
public static final ThingTypeUID THING_TYPE_COMPUTER = new ThingTypeUID(BINDING_ID, "computer");
// Thing properties
/**
* Number of CPU logical cores
*/
public static final String PROPERTY_CPU_LOGICAL_CORES = "CPU Logical Cores";
/**
* Number of CPU physical cores
*/
public static final String PROPERTY_CPU_PHYSICAL_CORES = "CPU Physical Cores";
/**
* Contains information about the family /Windows, Linux, OS X etc/ of the operation system
*/
public static final String PROPERTY_OS_FAMILY = "OS Family";
/**
* Name of the manufacturer of the operation system
*/
public static final String PROPERTY_OS_MANUFACTURER = "OS Manufacturer";
/**
* Version of the operation system
*/
public static final String PROPERTY_OS_VERSION = "OS Version";
// List of all Channel IDs
/**
* Size of the available memory
*/
public static final String CHANNEL_MEMORY_AVAILABLE = "memory#available";
/**
* Size of the used memory
*/
public static final String CHANNEL_MEMORY_USED = "memory#used";
/**
* Total size of the memory
*/
public static final String CHANNEL_MEMORY_TOTAL = "memory#total";
/**
* Percents of the available memory
*/
public static final String CHANNEL_MEMORY_AVAILABLE_PERCENT = "memory#availablePercent";
/**
* Percents of the used memory
*/
public static final String CHANNEL_MEMORY_USED_PERCENT = "memory#usedPercent";
/**
* Total size of swap memory
*/
public static final String CHANNEL_SWAP_TOTAL = "swap#total";
/**
* Size of the available swap memory
*/
public static final String CHANNEL_SWAP_AVAILABLE = "swap#available";
/**
* Size of the used swap memory
*/
public static final String CHANNEL_SWAP_USED = "swap#used";
/**
* Percents of the available swap memory
*/
public static final String CHANNEL_SWAP_AVAILABLE_PERCENT = "swap#availablePercent";
/**
* Percents of the used swap memory
*/
public static final String CHANNEL_SWAP_USED_PERCENT = "swap#usedPercent";
/**
* Physical storage drive name
*/
public static final String CHANNEL_DRIVE_NAME = "drive#name";
/**
* Physical storage drive model
*/
public static final String CHANNEL_DRIVE_MODEL = "drive#model";
/**
* Physical storage drive serial number
*/
public static final String CHANNEL_DRIVE_SERIAL = "drive#serial";
/**
* Name of the logical volume storage
*/
public static final String CHANNEL_STORAGE_NAME = "storage#name";
/**
* Logical storage volume type -(e.g. NTFS, FAT32 ..)
*/
public static final String CHANNEL_STORAGE_TYPE = "storage#type";
/**
* Description of the logical volume storage
*/
public static final String CHANNEL_STORAGE_DESCRIPTION = "storage#description";
/**
* Size of the available storage space
*/
public static final String CHANNEL_STORAGE_AVAILABLE = "storage#available";
/**
* Size of the used storage space
*/
public static final String CHANNEL_STORAGE_USED = "storage#used";
/**
* Total storage space
*/
public static final String CHANNEL_STORAGE_TOTAL = "storage#total";
/**
* Percents of the available storage space
*/
public static final String CHANNEL_STORAGE_AVAILABLE_PERCENT = "storage#availablePercent";
/**
* Percents of the used storage space
*/
public static final String CHANNEL_STORAGE_USED_PERCENT = "storage#usedPercent";
/**
* Temperature of the CPU measured from the sensors.
*/
public static final String CHANNEL_SENSORS_CPU_TEMPERATURE = "sensors#cpuTemp";
/**
* Voltage of the CPU core.
*/
public static final String CHANNEL_SENOSRS_CPU_VOLTAGE = "sensors#cpuVoltage";
/**
* Fan speed
*/
public static final String CHANNEL_SENSORS_FAN_SPEED = "sensors#fanSpeed";
/**
* Name of the battery
*/
public static final String CHANNEL_BATTERY_NAME = "battery#name";
/**
* Remaining capacity of the battery.
*/
public static final String CHANNEL_BATTERY_REMAINING_CAPACITY = "battery#remainingCapacity";
/**
* Estimated remaining time of the battery
*/
public static final String CHANNEL_BATTERY_REMAINING_TIME = "battery#remainingTime";
/**
* Detailed description about the CPU
*/
public static final String CHANNEL_CPU_DESCRIPTION = "cpu#description";
/**
* Average recent CPU load
*/
public static final String CHANNEL_CPU_LOAD = "cpu#load";
/**
* Average CPU load for the last minute
*/
public static final String CHANNEL_CPU_LOAD_1 = "cpu#load1";
/**
* Average CPU load for the last 5 minutes
*/
public static final String CHANNEL_CPU_LOAD_5 = "cpu#load5";
/**
* Average CPU load for the last 15 minutes
*/
public static final String CHANNEL_CPU_LOAD_15 = "cpu#load15";
/**
* CPU name
*/
public static final String CHANNEL_CPU_NAME = "cpu#name";
/**
* CPU uptime in minutes
*/
public static final String CHANNEL_CPU_UPTIME = "cpu#uptime";
/**
* CPU running threads count
*/
public static final String CHANNEL_CPU_THREADS = "cpu#threads";
/**
* Information about the display device
*/
public static final String CHANNEL_DISPLAY_INFORMATION = "display#information";
/**
* Host IP address of the network
*/
public static final String CHANNEL_NETWORK_IP = "network#ip";
/**
* Network display name
*/
public static final String CHANNEL_NETWORK_ADAPTER_NAME = "network#networkName";
/**
* Network data sent
*/
public static final String CHANNEL_NETWORK_DATA_SENT = "network#dataSent";
/**
* Network data received
*/
public static final String CHANNEL_NETWORK_DATA_RECEIVED = "network#dataReceived";
/**
* Network packets sent
*/
public static final String CHANNEL_NETWORK_PACKETS_SENT = "network#packetsSent";
/**
* Network packets received
*/
public static final String CHANNEL_NETWORK_PACKETS_RECEIVED = "network#packetsReceived";
/**
* Network name
*/
public static final String CHANNEL_NETWORK_NAME = "network#networkDisplayName";
/**
* Network mac address
*/
public static final String CHANNEL_NETWORK_MAC = "network#mac";
/**
* Name of the channel group for process information
*/
public static final String CHANNEL_GROUP_PROCESS = "process";
/**
* CPU load used from a process
*/
public static final String CHANNEL_PROCESS_LOAD = "process#load";
/**
* Size of memory used from a process in MB
*/
public static final String CHANNEL_PROCESS_MEMORY = "process#used";
/**
* Name of the process
*/
public static final String CHANNEL_PROCESS_NAME = "process#name";
/**
* Number of threads, used form the process
*/
public static final String CHANNEL_PROCESS_THREADS = "process#threads";
/**
* The full path of the process
*/
public static final String CHANNEL_PROCESS_PATH = "process#path";
// Thing configuraion
/**
* Name of the configuration parameter of the thing that defines refresh time for High priority channels
*/
public static final String HIGH_PRIORITY_REFRESH_TIME = "interval_high";
/**
* Name of the configuration parameter of the thing that defines refresh time for Medium priority channels
*/
public static final String MEDIUM_PRIORITY_REFRESH_TIME = "interval_medium";
// Channel configuration
/**
* Name of the channel configuration parameter priority
*/
public static final String PRIOIRITY_PARAM = "priority";
/**
* Name of the channel configuration parameter pid
*
*/
public static final String PID_PARAM = "pid";
}

View File

@@ -0,0 +1,72 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.systeminfo.internal;
import static org.openhab.binding.systeminfo.internal.SysteminfoBindingConstants.THING_TYPE_COMPUTER;
import java.util.Collections;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.systeminfo.internal.handler.SysteminfoHandler;
import org.openhab.binding.systeminfo.internal.model.SysteminfoInterface;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* The {@link SysteminfoHandlerFactory} is responsible for creating things and thing
* handlers.
*
* @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 @NonNullByDefault({}) SysteminfoInterface systeminfo;
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
}
@Override
protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (thingTypeUID.equals(THING_TYPE_COMPUTER)) {
return new SysteminfoHandler(thing, systeminfo);
}
return null;
}
@Reference
public void bindSystemInfo(SysteminfoInterface systeminfo) {
this.systeminfo = systeminfo;
}
public void unbindSystemInfo(SysteminfoInterface systeminfo) {
this.systeminfo = null;
}
}

View File

@@ -0,0 +1,88 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.systeminfo.internal.discovery;
import static org.openhab.binding.systeminfo.internal.SysteminfoBindingConstants.THING_TYPE_COMPUTER;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.systeminfo.internal.SysteminfoBindingConstants;
import org.openhab.core.config.discovery.AbstractDiscoveryService;
import org.openhab.core.config.discovery.DiscoveryResult;
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.ThingUID;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Discovery service implementation for the Systeminfo binding. It creates {@link DiscoveryResult} with
* {@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";
public static final String DEFAULT_THING_LABEL = "Local computer";
private final Logger logger = LoggerFactory.getLogger(SysteminfoDiscoveryService.class);
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_TYPE_COMPUTER);
private static final int DISCOVERY_TIME_SECONDS = 30;
private static final String THING_UID_VALID_CHARS = "A-Za-z0-9_-";
private static final String HOST_NAME_SEPERATOR = "_";
public SysteminfoDiscoveryService() {
super(SUPPORTED_THING_TYPES_UIDS, DISCOVERY_TIME_SECONDS);
}
@Override
protected void startScan() {
logger.debug("Starting system information discovery !");
String hostname;
try {
hostname = getHostName();
if (hostname.isEmpty()) {
throw new UnknownHostException();
}
if (!hostname.matches("[" + THING_UID_VALID_CHARS + "]*")) {
hostname = hostname.replaceAll("[^" + THING_UID_VALID_CHARS + "]", HOST_NAME_SEPERATOR);
}
} catch (UnknownHostException ex) {
hostname = DEFAULT_THING_ID;
logger.info("Hostname can not be resolved. Computer name will be set to the default one: {}",
DEFAULT_THING_ID);
}
ThingTypeUID computerType = SysteminfoBindingConstants.THING_TYPE_COMPUTER;
ThingUID computer = new ThingUID(computerType, hostname);
thingDiscovered(DiscoveryResultBuilder.create(computer).withLabel(DEFAULT_THING_LABEL).build());
}
protected String getHostName() throws UnknownHostException {
InetAddress addr = InetAddress.getLocalHost();
String hostname = addr.getHostName();
return hostname;
}
}

View File

@@ -0,0 +1,603 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.systeminfo.internal.handler;
import static org.openhab.binding.systeminfo.internal.SysteminfoBindingConstants.*;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.systeminfo.internal.model.DeviceNotFoundException;
import org.openhab.binding.systeminfo.internal.model.SysteminfoInterface;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.binding.BaseThingHandler;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link SysteminfoHandler} is responsible for providing real time information about the system
* (CPU, Memory, Storage, Display and others).
*
* @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 @NonNullByDefault({}) BigDecimal refreshIntervalHighPriority;
/**
* Refresh interval for {@link #mediumPriorityChannels} in seconds.
*/
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 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 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 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
* links have to be created before the thing state is updated, otherwise item state will not be updated.
*/
public static final int WAIT_TIME_CHANNEL_ITEM_LINK_INIT = 1;
private SysteminfoInterface systeminfo;
private @Nullable ScheduledFuture<?> highPriorityTasks;
private @Nullable ScheduledFuture<?> mediumPriorityTasks;
private Logger logger = LoggerFactory.getLogger(SysteminfoHandler.class);
public SysteminfoHandler(Thing thing, @Nullable SysteminfoInterface systeminfo) {
super(thing);
if (systeminfo != null) {
this.systeminfo = systeminfo;
} else {
throw new IllegalArgumentException("No systeminfo service was provided");
}
}
@Override
public void initialize() {
logger.debug("Start initializing!");
if (instantiateSysteminfoLibrary() && isConfigurationValid() && updateProperties()) {
groupChannelsByPriority();
scheduleUpdates();
logger.debug("Thing is successfully initialized!");
updateStatus(ThingStatus.ONLINE);
} else {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_INITIALIZING_ERROR,
"Thing cannot be initialized!");
}
}
private boolean instantiateSysteminfoLibrary() {
try {
systeminfo.initializeSysteminfo();
logger.debug("Systeminfo implementation is instantiated!");
return true;
} catch (Exception e) {
logger.warn("Cannot instantiate Systeminfo object!", e);
return false;
}
}
private boolean isConfigurationValid() {
logger.debug("Start reading Thing configuration.");
try {
refreshIntervalMediumPriority = (BigDecimal) this.thing.getConfiguration()
.get(MEDIUM_PRIORITY_REFRESH_TIME);
refreshIntervalHighPriority = (BigDecimal) this.thing.getConfiguration().get(HIGH_PRIORITY_REFRESH_TIME);
if (refreshIntervalHighPriority.intValue() <= 0 || refreshIntervalMediumPriority.intValue() <= 0) {
throw new IllegalArgumentException("Refresh time must be positive number!");
}
logger.debug("Refresh time for medium priority channels set to {} s", refreshIntervalMediumPriority);
logger.debug("Refresh time for high priority channels set to {} s", refreshIntervalHighPriority);
return true;
} catch (IllegalArgumentException e) {
logger.warn("Refresh time value is invalid! Please change the thing configuration!");
return false;
} catch (ClassCastException e) {
logger.debug("Channel configuration cannot be read!");
return false;
}
}
private boolean updateProperties() {
Map<String, String> properties = editProperties();
try {
properties.put(PROPERTY_CPU_LOGICAL_CORES, systeminfo.getCpuLogicalCores().toString());
properties.put(PROPERTY_CPU_PHYSICAL_CORES, systeminfo.getCpuPhysicalCores().toString());
properties.put(PROPERTY_OS_FAMILY, systeminfo.getOsFamily().toString());
properties.put(PROPERTY_OS_MANUFACTURER, systeminfo.getOsManufacturer().toString());
properties.put(PROPERTY_OS_VERSION, systeminfo.getOsVersion().toString());
updateProperties(properties);
logger.debug("Properties updated!");
return true;
} catch (Exception e) {
logger.debug("Cannot get system properties! Please try to restart the binding.", e);
return false;
}
}
private void groupChannelsByPriority() {
logger.trace("Grouping channels by priority.");
List<Channel> channels = this.thing.getChannels();
for (Channel channel : channels) {
Configuration properties = channel.getConfiguration();
String priority = (String) properties.get(PRIOIRITY_PARAM);
if (priority == null) {
logger.debug("Channel with UID {} will not be updated. The channel has no priority set !",
channel.getUID());
break;
}
switch (priority) {
case "High":
highPriorityChannels.add(channel.getUID());
break;
case "Medium":
mediumPriorityChannels.add(channel.getUID());
break;
case "Low":
lowPriorityChannels.add(channel.getUID());
break;
default:
logger.debug("Invalid priority configuration parameter. Channel will not be updated!");
}
}
}
private void changeChannelPriority(ChannelUID channelUID, String priority) {
switch (priority) {
case "High":
mediumPriorityChannels.remove(channelUID);
lowPriorityChannels.remove(channelUID);
highPriorityChannels.add(channelUID);
break;
case "Medium":
lowPriorityChannels.remove(channelUID);
highPriorityChannels.remove(channelUID);
mediumPriorityChannels.add(channelUID);
break;
case "Low":
highPriorityChannels.remove(channelUID);
mediumPriorityChannels.remove(channelUID);
lowPriorityChannels.add(channelUID);
break;
default:
logger.debug("Invalid priority configuration parameter. Channel will not be updated!");
}
}
private void scheduleUpdates() {
logger.debug("Schedule high priority tasks at fixed rate {} s.", refreshIntervalHighPriority);
highPriorityTasks = scheduler.scheduleWithFixedDelay(() -> {
publishData(highPriorityChannels);
}, WAIT_TIME_CHANNEL_ITEM_LINK_INIT, refreshIntervalHighPriority.intValue(), TimeUnit.SECONDS);
logger.debug("Schedule medium priority tasks at fixed rate {} s.", refreshIntervalMediumPriority);
mediumPriorityTasks = scheduler.scheduleWithFixedDelay(() -> {
publishData(mediumPriorityChannels);
}, WAIT_TIME_CHANNEL_ITEM_LINK_INIT, refreshIntervalMediumPriority.intValue(), TimeUnit.SECONDS);
logger.debug("Schedule one time update for low priority tasks.");
scheduler.schedule(() -> {
publishData(lowPriorityChannels);
}, WAIT_TIME_CHANNEL_ITEM_LINK_INIT, TimeUnit.SECONDS);
}
private void publishData(Set<ChannelUID> channels) {
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();
updateState(channelID, state);
}
public Set<ChannelUID> getHighPriorityChannels() {
return highPriorityChannels;
}
public Set<ChannelUID> getMediumPriorityChannels() {
return mediumPriorityChannels;
}
public Set<ChannelUID> getLowPriorityChannels() {
return lowPriorityChannels;
}
/**
* This method gets the information for specific channel through the {@link SysteminfoInterface}. It uses the
* channel ID to call the correct method from the {@link SysteminfoInterface} with deviceIndex parameter (in case of
* multiple devices, for reference see {@link #getDeviceIndex(String)}})
*
* @param channelUID the UID of the channel
* @return State object or null, if there is no information for the device with this index
*/
private State getInfoForChannel(ChannelUID channelUID) {
State state = null;
String channelID = channelUID.getId();
String channelIDWithoutGroup = channelUID.getIdWithoutGroup();
String channelGroupID = channelUID.getGroupId();
int deviceIndex = getDeviceIndex(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
if (channelGroupID != null) {
channelID = channelGroupID.replaceAll("\\d+", "") + "#" + channelIDWithoutGroup;
}
try {
switch (channelID) {
case CHANNEL_DISPLAY_INFORMATION:
state = systeminfo.getDisplayInformation(deviceIndex);
break;
case CHANNEL_BATTERY_NAME:
state = systeminfo.getBatteryName(deviceIndex);
break;
case CHANNEL_BATTERY_REMAINING_CAPACITY:
state = systeminfo.getBatteryRemainingCapacity(deviceIndex);
break;
case CHANNEL_BATTERY_REMAINING_TIME:
state = systeminfo.getBatteryRemainingTime(deviceIndex);
break;
case CHANNEL_SENSORS_CPU_TEMPERATURE:
state = systeminfo.getSensorsCpuTemperature();
break;
case CHANNEL_SENOSRS_CPU_VOLTAGE:
state = systeminfo.getSensorsCpuVoltage();
break;
case CHANNEL_SENSORS_FAN_SPEED:
state = systeminfo.getSensorsFanSpeed(deviceIndex);
break;
case CHANNEL_CPU_LOAD_1:
state = systeminfo.getCpuLoad1();
break;
case CHANNEL_CPU_LOAD_5:
state = systeminfo.getCpuLoad5();
break;
case CHANNEL_CPU_LOAD_15:
state = systeminfo.getCpuLoad15();
break;
case CHANNEL_CPU_UPTIME:
state = systeminfo.getCpuUptime();
break;
case CHANNEL_CPU_THREADS:
state = systeminfo.getCpuThreads();
break;
case CHANNEL_CPU_DESCRIPTION:
state = systeminfo.getCpuDescription();
break;
case CHANNEL_CPU_NAME:
state = systeminfo.getCpuName();
break;
case CHANNEL_MEMORY_AVAILABLE:
state = systeminfo.getMemoryAvailable();
break;
case CHANNEL_MEMORY_USED:
state = systeminfo.getMemoryUsed();
break;
case CHANNEL_MEMORY_TOTAL:
state = systeminfo.getMemoryTotal();
break;
case CHANNEL_MEMORY_AVAILABLE_PERCENT:
state = systeminfo.getMemoryAvailablePercent();
break;
case CHANNEL_MEMORY_USED_PERCENT:
state = systeminfo.getMemoryUsedPercent();
break;
case CHANNEL_SWAP_AVAILABLE:
state = systeminfo.getSwapAvailable();
break;
case CHANNEL_SWAP_USED:
state = systeminfo.getSwapUsed();
break;
case CHANNEL_SWAP_TOTAL:
state = systeminfo.getSwapTotal();
break;
case CHANNEL_SWAP_AVAILABLE_PERCENT:
state = systeminfo.getSwapAvailablePercent();
break;
case CHANNEL_SWAP_USED_PERCENT:
state = systeminfo.getSwapUsedPercent();
break;
case CHANNEL_DRIVE_MODEL:
state = systeminfo.getDriveModel(deviceIndex);
break;
case CHANNEL_DRIVE_SERIAL:
state = systeminfo.getDriveSerialNumber(deviceIndex);
break;
case CHANNEL_DRIVE_NAME:
state = systeminfo.getDriveName(deviceIndex);
break;
case CHANNEL_STORAGE_NAME:
state = systeminfo.getStorageName(deviceIndex);
break;
case CHANNEL_STORAGE_DESCRIPTION:
state = systeminfo.getStorageDescription(deviceIndex);
break;
case CHANNEL_STORAGE_AVAILABLE:
state = systeminfo.getStorageAvailable(deviceIndex);
break;
case CHANNEL_STORAGE_USED:
state = systeminfo.getStorageUsed(deviceIndex);
break;
case CHANNEL_STORAGE_TOTAL:
state = systeminfo.getStorageTotal(deviceIndex);
break;
case CHANNEL_STORAGE_TYPE:
state = systeminfo.getStorageType(deviceIndex);
break;
case CHANNEL_STORAGE_AVAILABLE_PERCENT:
state = systeminfo.getStorageAvailablePercent(deviceIndex);
break;
case CHANNEL_STORAGE_USED_PERCENT:
state = systeminfo.getStorageUsedPercent(deviceIndex);
break;
case CHANNEL_NETWORK_IP:
state = systeminfo.getNetworkIp(deviceIndex);
break;
case CHANNEL_NETWORK_ADAPTER_NAME:
state = systeminfo.getNetworkDisplayName(deviceIndex);
break;
case CHANNEL_NETWORK_NAME:
state = systeminfo.getNetworkName(deviceIndex);
break;
case CHANNEL_NETWORK_MAC:
state = systeminfo.getNetworkMac(deviceIndex);
break;
case CHANNEL_NETWORK_DATA_SENT:
state = systeminfo.getNetworkDataSent(deviceIndex);
break;
case CHANNEL_NETWORK_DATA_RECEIVED:
state = systeminfo.getNetworkDataReceived(deviceIndex);
break;
case CHANNEL_NETWORK_PACKETS_RECEIVED:
state = systeminfo.getNetworkPacketsReceived(deviceIndex);
break;
case CHANNEL_NETWORK_PACKETS_SENT:
state = systeminfo.getNetworkPacketsSent(deviceIndex);
break;
case CHANNEL_PROCESS_LOAD:
state = systeminfo.getProcessCpuUsage(deviceIndex);
break;
case CHANNEL_PROCESS_MEMORY:
state = systeminfo.getProcessMemoryUsage(deviceIndex);
break;
case CHANNEL_PROCESS_NAME:
state = systeminfo.getProcessName(deviceIndex);
break;
case CHANNEL_PROCESS_PATH:
state = systeminfo.getProcessPath(deviceIndex);
break;
case CHANNEL_PROCESS_THREADS:
state = systeminfo.getProcessThreads(deviceIndex);
break;
default:
logger.debug("Channel with unknown ID: {} !", channelID);
}
} catch (DeviceNotFoundException e) {
logger.warn("No information for channel {} with device index {} :", channelID, deviceIndex);
} catch (Exception e) {
logger.debug("Unexpected error occurred while getting system information!", e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Cannot get system info as result of unexpected error. Please try to restart the binding (remove and re-add the thing)!");
}
return state != null ? state : UnDefType.UNDEF;
}
/**
* The device index is an optional part of the channelID - the last characters of the groupID. It is used to
* identify unique device, when more than one devices are available (e.g. local disks with names C:\, D:\, E"\ - the
* first will have deviceIndex=0, the second deviceIndex=1 ant etc).
* When no device index is specified, default value of 0 (first device in the list) is returned.
*
* @param channelID the ID of the channel
* @return natural number (number >=0)
*/
private int getDeviceIndex(ChannelUID channelUID) {
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);
logger.debug("Channel with UID {} tracks process with PID: {}", channelUID, pid);
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 0;
}
/**
* This method gets the process identifier (PID) for specific process
*
* @param channelUID channel unique identifier
* @return natural number
*/
private int getPID(ChannelUID channelUID) {
int pid = 0;
try {
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 {
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) {
logger.debug("PID (Process Identifier) must be positive number. Fall back to default value. ", e);
}
return pid;
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
if (thing.getStatus().equals(ThingStatus.ONLINE)) {
if (command instanceof RefreshType) {
logger.debug("Refresh command received for channel {}!", channelUID);
publishDataForChannel(channelUID);
} else {
logger.debug("Unsupported command {}! Supported commands: REFRESH", command);
}
} else {
logger.debug("Cannot handle command. Thing is not ONLINE.");
}
}
private boolean isConfigurationKeyChanged(Configuration currentConfig, Configuration newConfig, String key) {
Object currentValue = currentConfig.get(key);
Object newValue = newConfig.get(key);
if (currentValue == null) {
return (newValue != null);
}
return !currentValue.equals(newValue);
}
@Override
public void thingUpdated(Thing thing) {
logger.trace("About to update thing.");
boolean isChannelConfigChanged = false;
List<Channel> channels = thing.getChannels();
for (Channel channel : channels) {
ChannelUID channelUID = channel.getUID();
Configuration newChannelConfig = channel.getConfiguration();
Channel oldChannel = this.thing.getChannel(channelUID.getId());
if (oldChannel == null) {
logger.warn("Channel with UID {} cannot be updated, as it cannot be found !", channelUID);
continue;
}
Configuration currentChannelConfig = oldChannel.getConfiguration();
if (isConfigurationKeyChanged(currentChannelConfig, newChannelConfig, PRIOIRITY_PARAM)) {
isChannelConfigChanged = true;
handleChannelConfigurationChange(oldChannel, newChannelConfig, PRIOIRITY_PARAM);
String newPriority = (String) newChannelConfig.get(PRIOIRITY_PARAM);
changeChannelPriority(channelUID, newPriority);
}
if (isConfigurationKeyChanged(currentChannelConfig, newChannelConfig, PID_PARAM)) {
isChannelConfigChanged = true;
handleChannelConfigurationChange(oldChannel, newChannelConfig, PID_PARAM);
}
}
if (!(isInitialized() && isChannelConfigChanged)) {
super.thingUpdated(thing);
}
}
private void handleChannelConfigurationChange(Channel channel, Configuration newConfig, String parameter) {
Configuration configuration = channel.getConfiguration();
Object oldValue = configuration.get(parameter);
configuration.put(parameter, newConfig.get(parameter));
Object newValue = newConfig.get(parameter);
logger.debug("Channel with UID {} has changed its {} from {} to {}", channel.getUID(), parameter, oldValue,
newValue);
publishDataForChannel(channel.getUID());
}
private void stopScheduledUpdates() {
ScheduledFuture<?> localHighPriorityTasks = highPriorityTasks;
if (localHighPriorityTasks != null) {
logger.debug("High prioriy tasks will not be run anymore !");
localHighPriorityTasks.cancel(true);
}
ScheduledFuture<?> localMediumPriorityTasks = mediumPriorityTasks;
if (localMediumPriorityTasks != null) {
logger.debug("Medium prioriy tasks will not be run anymore !");
localMediumPriorityTasks.cancel(true);
}
}
@Override
public void dispose() {
stopScheduledUpdates();
}
}

View File

@@ -0,0 +1,72 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.systeminfo.internal.model;
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;
/**
* Constructs an {@code DeviceNotFoundException} with {@code null}
* as its error detail message.
*/
public DeviceNotFoundException() {
super();
}
/**
* Constructs an {@code DeviceNotFoundException} with the specified detail message.
*
*
* @param message
* The detail message (which is saved for later retrieval
* by the {@link #getMessage()} method)
*/
public DeviceNotFoundException(String message) {
super(message);
}
/**
* Constructs an {@code DeviceNotFoundException} with the specified detail message
* and cause.
*
* <p>
* Note that the detail message associated with {@code cause} is
* <i>not</i> automatically incorporated into this exception's detail
* message.
*
* @param message
* The detail message (which is saved for later retrieval
* by the {@link #getMessage()} method)
*
* @param cause
* The cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A null value is permitted,
* and indicates that the cause is nonexistent or unknown.)
*
*/
public DeviceNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,639 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.systeminfo.internal.model;
import java.math.BigDecimal;
import org.apache.commons.lang.ArrayUtils;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.StringType;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.ComputerSystem;
import oshi.hardware.Display;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HWDiskStore;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.hardware.NetworkIF;
import oshi.hardware.PowerSource;
import oshi.hardware.Sensors;
import oshi.software.os.OSFileStore;
import oshi.software.os.OSProcess;
import oshi.software.os.OperatingSystem;
import oshi.util.EdidUtil;
/**
* This implementation of {@link SysteminfoInterface} is using the open source library OSHI to provide system
* information. OSHI is a free JNA-based (native) Operating System and Hardware Information library for Java.
*
* @author Svilen Valkanov - Initial contribution
* @author Lyubomir Papazov - Move the initialization logic that could potentially take long time to the
* initializeSysteminfo method
* @author Christoph Weitkamp - Update to OSHI 3.13.0 - Replaced deprecated method
* CentralProcessor#getSystemSerialNumber()
* @author Wouter Born - Update to OSHI 4.0.0 and add null annotations
*
* @see <a href="https://github.com/oshi/oshi">OSHI GitHub repository</a>
*/
@NonNullByDefault
@Component(service = SysteminfoInterface.class)
public class OSHISysteminfo implements SysteminfoInterface {
private final Logger logger = LoggerFactory.getLogger(OSHISysteminfo.class);
private @NonNullByDefault({}) HardwareAbstractionLayer hal;
// Dynamic objects (may be queried repeatedly)
private @NonNullByDefault({}) GlobalMemory memory;
private @NonNullByDefault({}) CentralProcessor cpu;
private @NonNullByDefault({}) Sensors sensors;
// Static objects, should be recreated on each request
private @NonNullByDefault({}) ComputerSystem computerSystem;
private @NonNullByDefault({}) OperatingSystem operatingSystem;
private @NonNullByDefault({}) NetworkIF[] networks;
private @NonNullByDefault({}) Display[] displays;
private @NonNullByDefault({}) OSFileStore[] fileStores;
private @NonNullByDefault({}) PowerSource[] powerSources;
private @NonNullByDefault({}) HWDiskStore[] drives;
public static final int PRECISION_AFTER_DECIMAL_SIGN = 1;
/**
* Some of the methods used in this constructor execute native code and require execute permissions
*
*/
public OSHISysteminfo() {
logger.debug("OSHISysteminfo service is created");
}
@Override
public void initializeSysteminfo() {
logger.debug("OSHISysteminfo service starts initializing");
SystemInfo systemInfo = new SystemInfo();
hal = systemInfo.getHardware();
// Doesn't need regular update, they may be queried repeatedly
memory = hal.getMemory();
cpu = hal.getProcessor();
sensors = hal.getSensors();
computerSystem = hal.getComputerSystem();
operatingSystem = systemInfo.getOperatingSystem();
networks = hal.getNetworkIFs();
displays = hal.getDisplays();
fileStores = operatingSystem.getFileSystem().getFileStores();
powerSources = hal.getPowerSources();
drives = hal.getDiskStores();
}
private Object getDevice(Object @Nullable [] devices, int index) throws DeviceNotFoundException {
if ((devices == null) || (devices.length <= index)) {
throw new DeviceNotFoundException("Device with index: " + index + " can not be found!");
}
return devices[index];
}
private OSProcess getProcess(int pid) throws DeviceNotFoundException {
OSProcess process = operatingSystem.getProcess(pid);
if (process == null) {
throw new DeviceNotFoundException("Error while getting information for process with PID " + pid);
}
return process;
}
@Override
public StringType getOsFamily() {
String osFamily = operatingSystem.getFamily();
return new StringType(osFamily);
}
@Override
public StringType getOsManufacturer() {
String osManufacturer = operatingSystem.getManufacturer();
return new StringType(osManufacturer);
}
@Override
public StringType getOsVersion() {
String osVersion = operatingSystem.getVersionInfo().toString();
return new StringType(osVersion);
}
@Override
public StringType getCpuName() {
String name = cpu.getProcessorIdentifier().getName();
return new StringType(name);
}
@Override
public StringType getCpuDescription() {
String model = cpu.getProcessorIdentifier().getModel();
String family = cpu.getProcessorIdentifier().getFamily();
String serialNumber = computerSystem.getSerialNumber();
String identifier = cpu.getProcessorIdentifier().getIdentifier();
String vendor = cpu.getProcessorIdentifier().getVendor();
String architecture = cpu.getProcessorIdentifier().isCpu64bit() ? "64 bit" : "32 bit";
String descriptionFormatString = "Model: %s %s,family: %s, vendor: %s, sn: %s, identifier: %s ";
String description = String.format(descriptionFormatString, model, architecture, family, vendor, serialNumber,
identifier);
return new StringType(description);
}
@Override
public DecimalType getCpuLogicalCores() {
int logicalProcessorCount = cpu.getLogicalProcessorCount();
return new DecimalType(logicalProcessorCount);
}
@Override
public DecimalType getCpuPhysicalCores() {
int physicalProcessorCount = cpu.getPhysicalProcessorCount();
return new DecimalType(physicalProcessorCount);
}
@Override
public DecimalType getMemoryTotal() {
long totalMemory = memory.getTotal();
totalMemory = getSizeInMB(totalMemory);
return new DecimalType(totalMemory);
}
@Override
public DecimalType getMemoryAvailable() {
long availableMemory = memory.getAvailable();
availableMemory = getSizeInMB(availableMemory);
return new DecimalType(availableMemory);
}
@Override
public DecimalType getMemoryUsed() {
long totalMemory = memory.getTotal();
long availableMemory = memory.getAvailable();
long usedMemory = totalMemory - availableMemory;
usedMemory = getSizeInMB(usedMemory);
return new DecimalType(usedMemory);
}
@Override
public DecimalType getStorageTotal(int index) throws DeviceNotFoundException {
OSFileStore fileStore = (OSFileStore) getDevice(fileStores, index);
fileStore.updateAtrributes();
long totalSpace = fileStore.getTotalSpace();
totalSpace = getSizeInMB(totalSpace);
return new DecimalType(totalSpace);
}
@Override
public DecimalType getStorageAvailable(int index) throws DeviceNotFoundException {
OSFileStore fileStore = (OSFileStore) getDevice(fileStores, index);
fileStore.updateAtrributes();
long freeSpace = fileStore.getUsableSpace();
freeSpace = getSizeInMB(freeSpace);
return new DecimalType(freeSpace);
}
@Override
public DecimalType getStorageUsed(int index) throws DeviceNotFoundException {
OSFileStore fileStore = (OSFileStore) getDevice(fileStores, index);
fileStore.updateAtrributes();
long totalSpace = fileStore.getTotalSpace();
long freeSpace = fileStore.getUsableSpace();
long usedSpace = totalSpace - freeSpace;
usedSpace = getSizeInMB(usedSpace);
return new DecimalType(usedSpace);
}
@Override
public @Nullable DecimalType getStorageAvailablePercent(int deviceIndex) throws DeviceNotFoundException {
OSFileStore fileStore = (OSFileStore) getDevice(fileStores, deviceIndex);
fileStore.updateAtrributes();
long totalSpace = fileStore.getTotalSpace();
long freeSpace = fileStore.getUsableSpace();
if (totalSpace > 0) {
double freePercentDecimal = (double) freeSpace / (double) totalSpace;
BigDecimal freePercent = getPercentsValue(freePercentDecimal);
return new DecimalType(freePercent);
} else {
return null;
}
}
@Override
public @Nullable DecimalType getStorageUsedPercent(int deviceIndex) throws DeviceNotFoundException {
OSFileStore fileStore = (OSFileStore) getDevice(fileStores, deviceIndex);
fileStore.updateAtrributes();
long totalSpace = fileStore.getTotalSpace();
long freeSpace = fileStore.getUsableSpace();
long usedSpace = totalSpace - freeSpace;
if (totalSpace > 0) {
double usedPercentDecimal = (double) usedSpace / (double) totalSpace;
BigDecimal usedPercent = getPercentsValue(usedPercentDecimal);
return new DecimalType(usedPercent);
} else {
return null;
}
}
@Override
public StringType getStorageName(int index) throws DeviceNotFoundException {
OSFileStore fileStore = (OSFileStore) getDevice(fileStores, index);
String name = fileStore.getName();
return new StringType(name);
}
@Override
public StringType getStorageType(int deviceIndex) throws DeviceNotFoundException {
OSFileStore fileStore = (OSFileStore) getDevice(fileStores, deviceIndex);
String type = fileStore.getType();
return new StringType(type);
}
@Override
public StringType getStorageDescription(int index) throws DeviceNotFoundException {
OSFileStore fileStore = (OSFileStore) getDevice(fileStores, index);
String description = fileStore.getDescription();
return new StringType(description);
}
@Override
public StringType getNetworkIp(int index) throws DeviceNotFoundException {
NetworkIF netInterface = (NetworkIF) getDevice(networks, index);
netInterface.updateAttributes();
String[] ipAddresses = netInterface.getIPv4addr();
String ipv4 = (String) getDevice(ipAddresses, 0);
return new StringType(ipv4);
}
@Override
public StringType getNetworkName(int index) throws DeviceNotFoundException {
NetworkIF netInterface = (NetworkIF) getDevice(networks, index);
String name = netInterface.getName();
return new StringType(name);
}
@Override
public StringType getNetworkDisplayName(int index) throws DeviceNotFoundException {
NetworkIF netInterface = (NetworkIF) getDevice(networks, index);
String adapterName = netInterface.getDisplayName();
return new StringType(adapterName);
}
@Override
public StringType getDisplayInformation(int index) throws DeviceNotFoundException {
Display display = (Display) getDevice(displays, index);
byte[] edid = display.getEdid();
String manufacturer = EdidUtil.getManufacturerID(edid);
String product = EdidUtil.getProductID(edid);
String serialNumber = EdidUtil.getSerialNo(edid);
int width = EdidUtil.getHcm(edid);
int height = EdidUtil.getVcm(edid);
String edidFormatString = "Product %s, manufacturer %s, SN: %s, Width: %d, Height: %d";
String edidInfo = String.format(edidFormatString, product, manufacturer, serialNumber, width, height);
return new StringType(edidInfo);
}
@Override
public @Nullable DecimalType getSensorsCpuTemperature() {
BigDecimal cpuTemp = new BigDecimal(sensors.getCpuTemperature());
cpuTemp = cpuTemp.setScale(PRECISION_AFTER_DECIMAL_SIGN, BigDecimal.ROUND_HALF_UP);
return cpuTemp.signum() == 1 ? new DecimalType(cpuTemp) : null;
}
@Override
public @Nullable DecimalType getSensorsCpuVoltage() {
BigDecimal cpuVoltage = new BigDecimal(sensors.getCpuVoltage());
cpuVoltage = cpuVoltage.setScale(PRECISION_AFTER_DECIMAL_SIGN, BigDecimal.ROUND_HALF_UP);
return cpuVoltage.signum() == 1 ? new DecimalType(cpuVoltage) : null;
}
@Override
public @Nullable DecimalType getSensorsFanSpeed(int index) throws DeviceNotFoundException {
int[] fanSpeeds = sensors.getFanSpeeds();
int speed = (int) getDevice(ArrayUtils.toObject(fanSpeeds), index);
return speed > 0 ? new DecimalType(speed) : null;
}
@Override
public @Nullable DecimalType getBatteryRemainingTime(int index) throws DeviceNotFoundException {
PowerSource powerSource = (PowerSource) getDevice(powerSources, index);
powerSource.updateAttributes();
double remainingTimeInSeconds = powerSource.getTimeRemainingEstimated();
// The getTimeRemaining() method returns (-1.0) if is calculating or (-2.0) if the time is unlimited.
BigDecimal remainingTime = getTimeInMinutes(remainingTimeInSeconds);
return remainingTime.signum() == 1 ? new DecimalType(remainingTime) : null;
}
@Override
public DecimalType getBatteryRemainingCapacity(int index) throws DeviceNotFoundException {
PowerSource powerSource = (PowerSource) getDevice(powerSources, index);
powerSource.updateAttributes();
double remainingCapacity = powerSource.getRemainingCapacityPercent();
BigDecimal remainingCapacityPercents = getPercentsValue(remainingCapacity);
return new DecimalType(remainingCapacityPercents);
}
@Override
public StringType getBatteryName(int index) throws DeviceNotFoundException {
PowerSource powerSource = (PowerSource) getDevice(powerSources, index);
String name = powerSource.getName();
return new StringType(name);
}
@Override
public @Nullable DecimalType getMemoryAvailablePercent() {
long availableMemory = memory.getAvailable();
long totalMemory = memory.getTotal();
if (totalMemory > 0) {
double freePercentDecimal = (double) availableMemory / (double) totalMemory;
BigDecimal freePercent = getPercentsValue(freePercentDecimal);
return new DecimalType(freePercent);
} else {
return null;
}
}
@Override
public @Nullable DecimalType getMemoryUsedPercent() {
long availableMemory = memory.getAvailable();
long totalMemory = memory.getTotal();
long usedMemory = totalMemory - availableMemory;
if (totalMemory > 0) {
double usedPercentDecimal = (double) usedMemory / (double) totalMemory;
BigDecimal usedPercent = getPercentsValue(usedPercentDecimal);
return new DecimalType(usedPercent);
} else {
return null;
}
}
@Override
public StringType getDriveName(int deviceIndex) throws DeviceNotFoundException {
HWDiskStore drive = (HWDiskStore) getDevice(drives, deviceIndex);
String name = drive.getName();
return new StringType(name);
}
@Override
public StringType getDriveModel(int deviceIndex) throws DeviceNotFoundException {
HWDiskStore drive = (HWDiskStore) getDevice(drives, deviceIndex);
String model = drive.getModel();
return new StringType(model);
}
@Override
public StringType getDriveSerialNumber(int deviceIndex) throws DeviceNotFoundException {
HWDiskStore drive = (HWDiskStore) getDevice(drives, deviceIndex);
String serialNumber = drive.getSerial();
return new StringType(serialNumber);
}
@Override
public @Nullable DecimalType getSwapTotal() {
long swapTotal = memory.getVirtualMemory().getSwapTotal();
swapTotal = getSizeInMB(swapTotal);
return new DecimalType(swapTotal);
}
@Override
public @Nullable DecimalType getSwapAvailable() {
long swapTotal = memory.getVirtualMemory().getSwapTotal();
long swapUsed = memory.getVirtualMemory().getSwapUsed();
long swapAvailable = swapTotal - swapUsed;
swapAvailable = getSizeInMB(swapAvailable);
return new DecimalType(swapAvailable);
}
@Override
public @Nullable DecimalType getSwapUsed() {
long swapUsed = memory.getVirtualMemory().getSwapUsed();
swapUsed = getSizeInMB(swapUsed);
return new DecimalType(swapUsed);
}
@Override
public @Nullable DecimalType getSwapAvailablePercent() {
long swapTotal = memory.getVirtualMemory().getSwapTotal();
long swapUsed = memory.getVirtualMemory().getSwapUsed();
long swapAvailable = swapTotal - swapUsed;
if (swapTotal > 0) {
double swapAvailablePercentDecimal = (double) swapAvailable / (double) swapTotal;
BigDecimal swapAvailablePercent = getPercentsValue(swapAvailablePercentDecimal);
return new DecimalType(swapAvailablePercent);
} else {
return null;
}
}
@Override
public @Nullable DecimalType getSwapUsedPercent() {
long swapTotal = memory.getVirtualMemory().getSwapTotal();
long swapUsed = memory.getVirtualMemory().getSwapUsed();
if (swapTotal > 0) {
double swapUsedPercentDecimal = (double) swapUsed / (double) swapTotal;
BigDecimal swapUsedPercent = getPercentsValue(swapUsedPercentDecimal);
return new DecimalType(swapUsedPercent);
} else {
return null;
}
}
private long getSizeInMB(long sizeInBytes) {
return Math.round(sizeInBytes / (1024D * 1024));
}
private BigDecimal getPercentsValue(double decimalFraction) {
BigDecimal result = new BigDecimal(decimalFraction * 100);
result = result.setScale(PRECISION_AFTER_DECIMAL_SIGN, BigDecimal.ROUND_HALF_UP);
return result;
}
private BigDecimal getTimeInMinutes(double timeInSeconds) {
BigDecimal timeInMinutes = new BigDecimal(timeInSeconds / 60);
timeInMinutes = timeInMinutes.setScale(PRECISION_AFTER_DECIMAL_SIGN, BigDecimal.ROUND_UP);
return timeInMinutes;
}
/**
* {@inheritDoc}
*
* This information is available only on Mac and Linux OS.
*/
@Override
public @Nullable DecimalType getCpuLoad1() {
BigDecimal avarageCpuLoad = getAvarageCpuLoad(1);
return avarageCpuLoad.signum() == -1 ? null : new DecimalType(avarageCpuLoad);
}
/**
* {@inheritDoc}
*
* This information is available only on Mac and Linux OS.
*/
@Override
public @Nullable DecimalType getCpuLoad5() {
BigDecimal avarageCpuLoad = getAvarageCpuLoad(5);
return avarageCpuLoad.signum() == -1 ? null : new DecimalType(avarageCpuLoad);
}
/**
* {@inheritDoc}
*
* This information is available only on Mac and Linux OS.
*/
@Override
public @Nullable DecimalType getCpuLoad15() {
BigDecimal avarageCpuLoad = getAvarageCpuLoad(15);
return avarageCpuLoad.signum() == -1 ? null : new DecimalType(avarageCpuLoad);
}
private BigDecimal getAvarageCpuLoad(int timeInMunutes) {
// This parameter is specified in OSHI Javadoc
int index;
switch (timeInMunutes) {
case 1:
index = 0;
break;
case 5:
index = 1;
break;
case 15:
index = 2;
break;
default:
index = 2;
}
double processorLoads[] = cpu.getSystemLoadAverage(index + 1);
BigDecimal result = new BigDecimal(processorLoads[index]);
result = result.setScale(PRECISION_AFTER_DECIMAL_SIGN, BigDecimal.ROUND_HALF_UP);
return result;
}
@Override
public DecimalType getCpuUptime() {
long seconds = operatingSystem.getSystemUptime();
return new DecimalType(getTimeInMinutes(seconds));
}
@Override
public DecimalType getCpuThreads() {
int threadCount = operatingSystem.getThreadCount();
return new DecimalType(threadCount);
}
@Override
public StringType getNetworkMac(int networkIndex) throws DeviceNotFoundException {
NetworkIF network = (NetworkIF) getDevice(networks, networkIndex);
String mac = network.getMacaddr();
return new StringType(mac);
}
@Override
public DecimalType getNetworkPacketsReceived(int networkIndex) throws DeviceNotFoundException {
NetworkIF network = (NetworkIF) getDevice(networks, networkIndex);
network.updateAttributes();
long packRecv = network.getPacketsRecv();
return new DecimalType(packRecv);
}
@Override
public DecimalType getNetworkPacketsSent(int networkIndex) throws DeviceNotFoundException {
NetworkIF network = (NetworkIF) getDevice(networks, networkIndex);
network.updateAttributes();
long packSent = network.getPacketsSent();
return new DecimalType(packSent);
}
@Override
public DecimalType getNetworkDataSent(int networkIndex) throws DeviceNotFoundException {
NetworkIF network = (NetworkIF) getDevice(networks, networkIndex);
network.updateAttributes();
long bytesSent = network.getBytesSent();
return new DecimalType(getSizeInMB(bytesSent));
}
@Override
public DecimalType getNetworkDataReceived(int networkIndex) throws DeviceNotFoundException {
NetworkIF network = (NetworkIF) getDevice(networks, networkIndex);
network.updateAttributes();
long bytesRecv = network.getBytesRecv();
return new DecimalType(getSizeInMB(bytesRecv));
}
@Override
public @Nullable StringType getProcessName(int pid) throws DeviceNotFoundException {
if (pid > 0) {
OSProcess process = getProcess(pid);
String name = process.getName();
return new StringType(name);
} else {
return null;
}
}
@Override
public @Nullable DecimalType getProcessCpuUsage(int pid) throws DeviceNotFoundException {
if (pid > 0) {
OSProcess process = getProcess(pid);
double cpuUsageRaw = (process.getKernelTime() + process.getUserTime()) / process.getUpTime();
BigDecimal cpuUsage = getPercentsValue(cpuUsageRaw);
return new DecimalType(cpuUsage);
} else {
return null;
}
}
@Override
public @Nullable DecimalType getProcessMemoryUsage(int pid) throws DeviceNotFoundException {
if (pid > 0) {
OSProcess process = getProcess(pid);
long memortInBytes = process.getResidentSetSize();
long memoryInMB = getSizeInMB(memortInBytes);
return new DecimalType(memoryInMB);
} else {
return null;
}
}
@Override
public @Nullable StringType getProcessPath(int pid) throws DeviceNotFoundException {
if (pid > 0) {
OSProcess process = getProcess(pid);
String path = process.getPath();
return new StringType(path);
} else {
return null;
}
}
@Override
public @Nullable DecimalType getProcessThreads(int pid) throws DeviceNotFoundException {
if (pid > 0) {
OSProcess process = getProcess(pid);
int threadCount = process.getThreadCount();
return new DecimalType(threadCount);
} else {
return null;
}
}
}

View File

@@ -0,0 +1,440 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.systeminfo.internal.model;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.StringType;
/**
* {@link SysteminfoInterface} defines the methods needed to provide this binding with the required system information.
*
* @author Svilen Valkanov - Initial contribution
* @author Wouter Born - Add null annotations
*/
@NonNullByDefault
public interface SysteminfoInterface {
/**
* Initialize logic for the Systeminfo implementation
*/
public void initializeSysteminfo();
// Operating system info
/**
* Get the Family of the operating system /e.g. Windows,Unix,.../
*/
public StringType getOsFamily();
/**
* Get the manufacturer of the operating system
*/
public StringType getOsManufacturer();
/**
* Get the version of the operating system
*
* @return
*/
public StringType getOsVersion();
// CPU info
/**
* Get the name of the CPU
*/
public StringType getCpuName();
/**
* Get description about the CPU e.g (model, family, vendor, serial number, identifier, architecture(32bit or
* 64bit))
*/
public StringType getCpuDescription();
/**
* Get the number of logical CPUs/cores available for processing.
*/
public DecimalType getCpuLogicalCores();
/**
* Get the number of physical CPUs/cores available for processing.
*/
public DecimalType getCpuPhysicalCores();
/**
* Returns the system load average for the last minute.
*
* @return the load as a number of processes or null, if no information is available
*/
public @Nullable DecimalType getCpuLoad1();
/**
* Returns the system load average for the last 5 minutes.
*
* @return the load as number of processes or null, if no information is available
*/
public @Nullable DecimalType getCpuLoad5();
/**
* Returns the system load average for the last 15 minutes.
*
* @return the load as number of processes or null, if no information is available
*/
public @Nullable DecimalType getCpuLoad15();
/**
* Get the System uptime (time since boot).
*
* @return time in minutes since boot
*/
public DecimalType getCpuUptime();
/**
* Get the number of threads currently running
*
* @return number of threads
*/
public DecimalType getCpuThreads();
// Memory info
/**
* Returns total size of memory
*
* @return memory size in MB
*/
public DecimalType getMemoryTotal();
/**
* Returns available size of memory
*
* @return memory size in MB
*/
public DecimalType getMemoryAvailable();
/**
* Returns used size of memory
*
* @return memory size in MB
*/
public DecimalType getMemoryUsed();
/**
* Percents of available memory on the machine
*
* @return percent of available memory or null, if no information is available
*/
public @Nullable DecimalType getMemoryAvailablePercent();
/**
* Percents of used memory on the machine
*
* @return percent of used memory or null, if no information is available
*/
public @Nullable DecimalType getMemoryUsedPercent();
// Swap memory info
/**
* Returns total size of swap memory
*
* @return memory size in MB or 0, if no there is no swap memory
*/
public @Nullable DecimalType getSwapTotal();
/**
* Returns available size swap of memory
*
* @return memory size in MB or 0, if no there is no swap memory
*/
public @Nullable DecimalType getSwapAvailable();
/**
* Returns used size of swap memory
*
* @return memory size in MB or 0, if no there is no swap memory
*/
public @Nullable DecimalType getSwapUsed();
/**
* Percents of available swap memory on the machine
*
* @return percent of available memory or null, if no there is no swap memory
*/
public @Nullable DecimalType getSwapAvailablePercent();
/**
* Percents of used swap memory on the machine
*
* @return percent of used memory or null, if no there is no swap memory
*/
public @Nullable DecimalType getSwapUsedPercent();
// Storage info
/**
* Returns the total space of the logical storage volume.
*
* @param deviceIndex - the index of the logical volume
* @return storage size in MB
* @throws DeviceNotFoundException
*/
public DecimalType getStorageTotal(int deviceIndex) throws DeviceNotFoundException;
/**
* Returns the available storage space on the logical storage volume
*
* @param deviceIndex - the index of the logical volume
* @return storage size in MB
* @throws DeviceNotFoundException
*/
public DecimalType getStorageAvailable(int deviceIndex) throws DeviceNotFoundException;
/**
* Gets the used storage space on the logical storage volume
*
* @param deviceIndex - the index of the logical volume
* @return storage size in MB
* @throws DeviceNotFoundException
*/
public DecimalType getStorageUsed(int deviceIndex) throws DeviceNotFoundException;
/**
* Gets the percent of available storage on the logical volume
*
* @param deviceIndex - the index of the logical volume
* @return percent of available storage or null
* @throws DeviceNotFoundException
*/
public @Nullable DecimalType getStorageAvailablePercent(int deviceIndex) throws DeviceNotFoundException;
/**
* Gets the percent of used storage on the logical volume
*
* @param deviceIndex - the index of the logical volume
* @return percent of used storage or null
* @throws DeviceNotFoundException
*/
public @Nullable DecimalType getStorageUsedPercent(int deviceIndex) throws DeviceNotFoundException;
/**
* Gets the name of the logical storage volume
*
* @throws DeviceNotFoundException
*/
public StringType getStorageName(int deviceIndex) throws DeviceNotFoundException;
/**
* Gets the type of the logical storage volume (e.g. NTFS, FAT32)
*
* @throws DeviceNotFoundException
*/
public StringType getStorageType(int deviceIndex) throws DeviceNotFoundException;
/**
* Gets the description of the logical storage volume
*
* @throws DeviceNotFoundException
*/
public StringType getStorageDescription(int deviceIndex) throws DeviceNotFoundException;
// Hardware drive info
/**
* Gets the name of the physical storage drive
*
* @param deviceIndex - index of the storage drive
* @throws DeviceNotFoundException
*/
public StringType getDriveName(int deviceIndex) throws DeviceNotFoundException;
/**
* Gets the model of the physical storage drive
*
* @param deviceIndex - index of the storage drive
* @throws DeviceNotFoundException
*/
public StringType getDriveModel(int deviceIndex) throws DeviceNotFoundException;
/**
* Gets the serial number of the physical storage drive
*
* @param deviceIndex - index of the storage drive
* @throws DeviceNotFoundException
*/
public StringType getDriveSerialNumber(int deviceIndex) throws DeviceNotFoundException;
// Network info
/**
* Get the Host IP address of the network.
*
* @param networkIndex - the index of the network
* @return 32-bit IPv4 address
* @throws DeviceNotFoundException
*/
public StringType getNetworkIp(int networkIndex) throws DeviceNotFoundException;
/**
* Get the name of this network.
*
* @param networkIndex - the index of the network
* @throws DeviceNotFoundException
*/
public StringType getNetworkName(int networkIndex) throws DeviceNotFoundException;
/**
* The description of the network. On some platforms, this is identical to the name.
*
* @param networkIndex - the index of the network
* @throws DeviceNotFoundException
*/
public StringType getNetworkDisplayName(int networkIndex) throws DeviceNotFoundException;
/**
* Gets the MAC Address of the network.
*
* @param networkIndex - the index of the network
* @throws DeviceNotFoundException
*/
public StringType getNetworkMac(int networkIndex) throws DeviceNotFoundException;
/**
* Get number of packets received
*
* @param networkIndex - the index of the network
* @throws DeviceNotFoundException
*/
public DecimalType getNetworkPacketsReceived(int networkIndex) throws DeviceNotFoundException;
/**
* Get number of packets sent
*
* @param networkIndex - the index of the network
* @throws DeviceNotFoundException
*/
public DecimalType getNetworkPacketsSent(int networkIndex) throws DeviceNotFoundException;
/**
* Get data sent in MB for this network
*
* @param networkIndex - the index of the network
* @throws DeviceNotFoundException
*/
public DecimalType getNetworkDataSent(int networkIndex) throws DeviceNotFoundException;
/**
* Get data received in MB for this network
*
* @param networkIndex - the index of the network
* @throws DeviceNotFoundException
*/
public DecimalType getNetworkDataReceived(int networkIndex) throws DeviceNotFoundException;
// Display info
/**
* Get information about the display device as product number, manufacturer, serial number, width and height in cm";
*
* @param deviceIndex - the index of the display device
* @throws DeviceNotFoundException
*/
public StringType getDisplayInformation(int deviceIndex) throws DeviceNotFoundException;
// Sensors info
/**
* Get the information from the CPU temperature sensors.
*
* @return Temperature in degrees Celsius if available, null otherwise.
*/
public @Nullable DecimalType getSensorsCpuTemperature();
/**
* Get the information for the CPU voltage.
*
* @return Voltage in Volts if available, null otherwise.
*/
public @Nullable DecimalType getSensorsCpuVoltage();
/**
* Get fan speed
*
* @param deviceIndex
* @return Speed in rpm or null if unable to measure fan speed
* @throws DeviceNotFoundException
*/
public @Nullable DecimalType getSensorsFanSpeed(int deviceIndex) throws DeviceNotFoundException;
// Battery info
/**
* Get estimated time remaining for the power source.
*
* @param deviceIndex
* @return minutes remaining charge or null, if the time is estimated as unlimited
* @throws DeviceNotFoundException
*/
public @Nullable DecimalType getBatteryRemainingTime(int deviceIndex) throws DeviceNotFoundException;
/**
* Battery remaining capacity.
*
* @param deviceIndex
* @return percentage value /0-100/
* @throws DeviceNotFoundException
*/
public DecimalType getBatteryRemainingCapacity(int deviceIndex) throws DeviceNotFoundException;
/**
* Get battery name
*
* @param deviceIndex
* @throws DeviceNotFoundException
*/
public StringType getBatteryName(int deviceIndex) throws DeviceNotFoundException;
/**
* Returns the name of the process
*
* @param pid - the PID of the process
* @throws DeviceNotFoundException - thrown if process with this PID can not be found
*/
public @Nullable StringType getProcessName(int pid) throws DeviceNotFoundException;
/**
* Returns the CPU usage of the process
*
* @param pid - the PID of the process
* @return - percentage value /0-100/
* @throws DeviceNotFoundException - thrown if process with this PID can not be found
*/
public @Nullable DecimalType getProcessCpuUsage(int pid) throws DeviceNotFoundException;
/**
* Returns the size of RAM memory only usage of the process
*
* @param pid - the PID of the process
* @return memory size in MB
* @throws DeviceNotFoundException- thrown if process with this PID can not be found
*/
public @Nullable DecimalType getProcessMemoryUsage(int pid) throws DeviceNotFoundException;
/**
* Returns the full path of the executing process.
*
* @param pid - the PID of the process
* @throws DeviceNotFoundException - thrown if process with this PID can not be found
*/
public @Nullable StringType getProcessPath(int pid) throws DeviceNotFoundException;
/**
* Returns the number of threads in this process.
*
* @param pid - the PID of the process
* @throws DeviceNotFoundException - thrown if process with this PID can not be found
*/
public @Nullable DecimalType getProcessThreads(int pid) throws DeviceNotFoundException;
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<binding:binding id="systeminfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
<name>Systeminfo Binding</name>
<description>This binding provides information about the operating system and the hardware.</description>
<author>Svilen Valkanov</author>
</binding:binding>

View File

@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<config-description:config-descriptions
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:config-description="https://openhab.org/schemas/config-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0
https://openhab.org/schemas/config-description-1.0.0.xsd">
<!-- Channels use the priority configuration parameter to inform the binding how often the channel state must be updated.
High priority should be channels, which change its state dynamically at few seconds interval. Medium priority channels
usually need update of the state more often - at several minutes. Low priority channels do not change their state at all,
or very often. They do not need regular updates. -->
<config-description uri="systeminfo:channels:lowpriority">
<parameter-group name="priorityGroup">
<label>String</label>
<description>String</description>
<advanced>false</advanced>
</parameter-group>
<parameter name="priority" type="text">
<label>Interval</label>
<description>Refresh interval in seconds.</description>
<options>
<option value="High">High</option>
<option value="Medium">Medium</option>
<option value="Low">Low</option>
</options>
<default>Low</default>
</parameter>
</config-description>
<config-description uri="systeminfo:channels:mediumpriority">
<parameter name="priority" type="text">
<label>Interval</label>
<description>Refresh interval in seconds.</description>
<options>
<option value="High">High</option>
<option value="Medium">Medium</option>
<option value="Low">Low</option>
</options>
<default>Medium</default>
</parameter>
</config-description>
<config-description uri="systeminfo:channels:highpriority">
<parameter name="priority" type="text">
<label>Interval</label>
<description>Refresh interval in seconds.</description>
<options>
<option value="High">High</option>
<option value="Medium">Medium</option>
<option value="Low">Low</option>
</options>
<default>High</default>
</parameter>
</config-description>
<config-description uri="systeminfo:channels:lowpriority_process">
<parameter name="priority" type="text">
<label>Interval</label>
<description>Refresh interval in seconds.</description>
<options>
<option value="High">High</option>
<option value="Medium">Medium</option>
<option value="Low">Low</option>
</options>
<default>Low</default>
</parameter>
<parameter name="pid" type="integer" min="0" step="1">
<label>PID</label>
<description>The Process Identifier of the process.</description>
<default>0</default>
</parameter>
</config-description>
<config-description uri="systeminfo:channels:mediumpriority_process">
<parameter name="priority" type="text">
<label>Interval</label>
<description>Refresh interval in seconds.</description>
<options>
<option value="High">High</option>
<option value="Medium">Medium</option>
<option value="Low">Low</option>
</options>
<default>Medium</default>
</parameter>
<parameter name="pid" type="integer" min="0" step="1">
<label>PID</label>
<description>The Process Identifier of the process.</description>
<default>0</default>
</parameter>
</config-description>
<config-description uri="systeminfo:channels:highpriority_process">
<parameter name="priority" type="text">
<label>Interval</label>
<description>Refresh interval in seconds.</description>
<options>
<option value="High">High</option>
<option value="Medium">Medium</option>
<option value="Low">Low</option>
</options>
<default>High</default>
</parameter>
<parameter name="pid" type="integer" min="0" step="1">
<label>PID</label>
<description>The Process Identifier of the process.</description>
<default>0</default>
</parameter>
</config-description>
</config-description:config-descriptions>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<config-description:config-descriptions
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:config-description="https://openhab.org/schemas/config-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0
https://openhab.org/schemas/config-description-1.0.0.xsd">
<!-- The thing updates at intervals the High and Medium priority channels, defined in channel configuration file. This parameters
specify how often (time in seconds) these channels should be updated. -->
<config-description uri="thing-type:systeminfo:computerConfig">
<parameter name="interval_high" type="integer">
<label>Interval for High Priority Tasks</label>
<description>Refresh interval in seconds.</description>
<default>1</default>
</parameter>
<parameter name="interval_medium" type="integer">
<label>Interval for Medium Priority Tasks</label>
<description>Refresh interval in seconds.</description>
<default>60</default>
</parameter>
<!-- Parameter "interval_low" is not needed, because channels with priority set to low are not updated periodically. They
are updated only at initializing or at REFRESH command. -->
</config-description>
</config-description:config-descriptions>

View File

@@ -0,0 +1,384 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="systeminfo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
<!-- This file contains channel specific information and describes how the different channel types should be rendered. Each
channel is assigned a default priority configuration. For more info about priorities see OH-INF/config/channelConfig.xml -->
<channel-group-type id="memoryGroup">
<label>Physical Memory</label>
<description>Physical memory information</description>
<channels>
<channel id="total" typeId="total"/>
<channel id="available" typeId="available"/>
<channel id="used" typeId="used"/>
<channel id="availablePercent" typeId="availablePercent"/>
<channel id="usedPercent" typeId="usedPercent"/>
</channels>
</channel-group-type>
<channel-group-type id="swapGroup">
<label>Swap Memory</label>
<description>Swap memory information</description>
<channels>
<channel id="total" typeId="total"/>
<channel id="available" typeId="available"/>
<channel id="used" typeId="used"/>
<channel id="availablePercent" typeId="availablePercent"/>
<channel id="usedPercent" typeId="usedPercent"/>
</channels>
</channel-group-type>
<channel-group-type id="storageGroup">
<label>Storage</label>
<description>Logical storage information</description>
<channels>
<channel id="total" typeId="total"/>
<channel id="available" typeId="available"/>
<channel id="used" typeId="used"/>
<channel id="availablePercent" typeId="availablePercent"/>
<channel id="usedPercent" typeId="usedPercent"/>
<channel id="name" typeId="name"/>
<channel id="description" typeId="description"/>
<channel id="type" typeId="type"/>
</channels>
</channel-group-type>
<channel-group-type id="driveGroup">
<label>Drive</label>
<description>Drive information</description>
<channels>
<channel id="name" typeId="name"/>
<channel id="model" typeId="model"/>
<channel id="serial" typeId="serial"/>
</channels>
</channel-group-type>
<channel-group-type id="networkGroup">
<label>Network</label>
<description>Network parameters</description>
<channels>
<channel id="ip" typeId="ip"/>
<channel id="networkName" typeId="networkName"/>
<channel id="networkDisplayName" typeId="networkDisplayName"/>
<channel id="dataSent" typeId="dataSent"/>
<channel id="dataReceived" typeId="dataReceived"/>
<channel id="packetsSent" typeId="packetsSent"/>
<channel id="packetsReceived" typeId="packetsReceived"/>
<channel id="mac" typeId="mac"/>
</channels>
</channel-group-type>
<channel-group-type id="displayGroup">
<label>Display</label>
<description>Display parameters</description>
<channels>
<channel id="information" typeId="information"/>
</channels>
</channel-group-type>
<channel-group-type id="sensorsGroup">
<label>Sensor</label>
<description>Sensor parameters</description>
<channels>
<channel id="cpuTemp" typeId="cpuTemp"/>
<channel id="cpuVoltage" typeId="cpuVoltage"/>
<channel id="fanSpeed" typeId="fanSpeed"/>
</channels>
</channel-group-type>
<channel-group-type id="batteryGroup">
<label>Battery</label>
<description>Battery parameters</description>
<channels>
<channel id="name" typeId="name"/>
<channel id="remainingCapacity" typeId="remainingCapacity"/>
<channel id="remainingTime" typeId="remainingTime"/>
</channels>
</channel-group-type>
<channel-group-type id="cpuGroup">
<label>CPU</label>
<description>CPU parameters</description>
<channels>
<channel id="name" typeId="name"/>
<channel id="description" typeId="description"/>
<channel id="load1" typeId="loadAverage"/>
<channel id="load5" typeId="loadAverage"/>
<channel id="load15" typeId="loadAverage"/>
<channel id="uptime" typeId="uptime"/>
<channel id="threads" typeId="threads"/>
</channels>
</channel-group-type>
<channel-group-type id="processGroup">
<label>Process</label>
<description>System process information</description>
<channels>
<channel id="load" typeId="load_process"/>
<channel id="used" typeId="used_process"/>
<channel id="name" typeId="name_process"/>
<channel id="threads" typeId="threads_process"/>
<channel id="path" typeId="path_process"/>
</channels>
</channel-group-type>
<channel-type id="path_process">
<item-type>String</item-type>
<label>Path</label>
<description>The full path</description>
<state readOnly="true" pattern="%s"/>
<config-description-ref uri="systeminfo:channels:lowpriority_process"/>
</channel-type>
<channel-type id="available">
<item-type>Number</item-type>
<label>Available</label>
<description>Available size in MB</description>
<state readOnly="true" pattern="%d MB"/>
<config-description-ref uri="systeminfo:channels:highpriority"/>
</channel-type>
<channel-type id="used">
<item-type>Number</item-type>
<label>Used</label>
<description>Used size in MB</description>
<state readOnly="true" pattern="%d MB"/>
<config-description-ref uri="systeminfo:channels:highpriority"/>
</channel-type>
<channel-type id="used_process">
<item-type>Number</item-type>
<label>Used</label>
<description>Used size in MB</description>
<state readOnly="true" pattern="%d MB"/>
<config-description-ref uri="systeminfo:channels:highpriority_process"/>
</channel-type>
<channel-type id="total">
<item-type>Number</item-type>
<label>Total</label>
<description>Total size in MB</description>
<state readOnly="true" pattern="%d MB"/>
<config-description-ref uri="systeminfo:channels:lowpriority"/>
</channel-type>
<channel-type id="availablePercent">
<item-type>Number</item-type>
<label>Available (%)</label>
<description>Available size in percent</description>
<state readOnly="true" pattern="%.1f %%"/>
<config-description-ref uri="systeminfo:channels:highpriority"/>
</channel-type>
<channel-type id="usedPercent">
<item-type>Number</item-type>
<label>Used (%)</label>
<description>Used size in percent</description>
<state readOnly="true" pattern="%.1f %%"/>
<config-description-ref uri="systeminfo:channels:highpriority"/>
</channel-type>
<channel-type id="name">
<item-type>String</item-type>
<label>Name</label>
<description>Name of the device (process)</description>
<state readOnly="true" pattern="%s"/>
<config-description-ref uri="systeminfo:channels:lowpriority"/>
</channel-type>
<channel-type id="name_process">
<item-type>String</item-type>
<label>Name</label>
<description>Name of the device (process)</description>
<state readOnly="true" pattern="%s"/>
<config-description-ref uri="systeminfo:channels:lowpriority_process"/>
</channel-type>
<channel-type id="model" advanced="true">
<item-type>String</item-type>
<label>Model</label>
<description>The model of the device</description>
<state readOnly="true" pattern="%s"/>
<config-description-ref uri="systeminfo:channels:lowpriority"/>
</channel-type>
<channel-type id="serial" advanced="true">
<item-type>String</item-type>
<label>Serial Number</label>
<description>The serial number of the device</description>
<state readOnly="true" pattern="%s"/>
<config-description-ref uri="systeminfo:channels:lowpriority"/>
</channel-type>
<channel-type id="description" advanced="true">
<item-type>String</item-type>
<label>Description</label>
<description>Description of the device</description>
<state readOnly="true" pattern="%s "/>
<config-description-ref uri="systeminfo:channels:lowpriority"/>
</channel-type>
<channel-type id="type" advanced="true">
<item-type>String</item-type>
<label>Type</label>
<description>Storage type</description>
<state readOnly="true" pattern="%s "/>
<config-description-ref uri="systeminfo:channels:lowpriority"/>
</channel-type>
<channel-type id="cpuTemp" advanced="true">
<item-type>Number</item-type>
<label>CPU Temperature</label>
<description>CPU Temperature in Celsius degrees</description>
<state readOnly="true" pattern="%.1f °"/>
<config-description-ref uri="systeminfo:channels:highpriority"/>
</channel-type>
<channel-type id="cpuVoltage" advanced="true">
<item-type>Number</item-type>
<label>CPU Voltage</label>
<description>CPU Voltage in V</description>
<state readOnly="true" pattern="%.1f V"/>
<config-description-ref uri="systeminfo:channels:mediumpriority"/>
</channel-type>
<channel-type id="fanSpeed" advanced="true">
<item-type>Number</item-type>
<label>Fan Speed</label>
<description>Fan speed in rpm</description>
<state readOnly="true" pattern="%d rpm"/>
<config-description-ref uri="systeminfo:channels:mediumpriority"/>
</channel-type>
<channel-type id="remainingTime">
<item-type>Number</item-type>
<label>Remaining Time</label>
<description>Remaining time in minutes</description>
<state readOnly="true" pattern="%.1f Minutes"/>
<config-description-ref uri="systeminfo:channels:mediumpriority"/>
</channel-type>
<channel-type id="remainingCapacity">
<item-type>Number</item-type>
<label>Remaining Capacity</label>
<description>Remaining capacity in percent</description>
<state readOnly="true" pattern="%.1f %%"/>
<config-description-ref uri="systeminfo:channels:mediumpriority"/>
</channel-type>
<channel-type id="load_process">
<item-type>Number</item-type>
<label>Load</label>
<description>Load in percent</description>
<state readOnly="true" pattern="%.1f %%"/>
<config-description-ref uri="systeminfo:channels:highpriority_process"/>
</channel-type>
<channel-type id="loadAverage" advanced="true">
<item-type>Number</item-type>
<label>Load Average</label>
<description>Load as a number of processes for the last 1,5 or 15 minutes</description>
<state readOnly="true" pattern="%.1f"/>
<config-description-ref uri="systeminfo:channels:mediumpriority"/>
</channel-type>
<channel-type id="uptime" advanced="true">
<item-type>Number</item-type>
<label>System Uptime</label>
<description>System uptime (time after start) in minutes</description>
<state readOnly="true" pattern="%.1f Minutes"/>
<config-description-ref uri="systeminfo:channels:mediumpriority"/>
</channel-type>
<channel-type id="threads" advanced="true">
<item-type>Number</item-type>
<label>Number of Threads</label>
<description>Number of threads currently running</description>
<state readOnly="true" pattern="%d"/>
<config-description-ref uri="systeminfo:channels:mediumpriority"/>
</channel-type>
<channel-type id="threads_process" advanced="true">
<item-type>Number</item-type>
<label>Number of Threads</label>
<description>Number of threads currently running</description>
<state readOnly="true" pattern="%d"/>
<config-description-ref uri="systeminfo:channels:mediumpriority_process"/>
</channel-type>
<channel-type id="information" advanced="true">
<item-type>String</item-type>
<label>Display Information</label>
<description>Product, manufacturer, SN, width and height of the display in cm</description>
<state readOnly="true" pattern="%s "/>
<config-description-ref uri="systeminfo:channels:lowpriority"/>
</channel-type>
<channel-type id="ip">
<item-type>String</item-type>
<label>IP Address</label>
<description>Host IP address of the network</description>
<state readOnly="true" pattern="%s "/>
<config-description-ref uri="systeminfo:channels:lowpriority"/>
</channel-type>
<channel-type id="mac" advanced="true">
<item-type>String</item-type>
<label>Mac Address</label>
<description>Mac address of the network</description>
<state readOnly="true" pattern="%s "/>
<config-description-ref uri="systeminfo:channels:lowpriority"/>
</channel-type>
<channel-type id="networkName">
<item-type>String</item-type>
<label>Network Name</label>
<description>The name of the network.</description>
<state readOnly="true" pattern="%s "/>
<config-description-ref uri="systeminfo:channels:lowpriority"/>
</channel-type>
<channel-type id="networkDisplayName">
<item-type>String</item-type>
<label>Network Display Name</label>
<description>The display name of the network</description>
<state readOnly="true" pattern="%s "/>
<config-description-ref uri="systeminfo:channels:lowpriority"/>
</channel-type>
<channel-type id="packetsSent" advanced="true">
<item-type>Number</item-type>
<label>Packets Sent</label>
<description>Number of packets sent</description>
<state readOnly="true" pattern="%d "/>
<config-description-ref uri="systeminfo:channels:mediumpriority"/>
</channel-type>
<channel-type id="packetsReceived" advanced="true">
<item-type>Number</item-type>
<label>Packets Received</label>
<description>Number of packets received</description>
<state readOnly="true" pattern="%d "/>
<config-description-ref uri="systeminfo:channels:mediumpriority"/>
</channel-type>
<channel-type id="dataSent" advanced="true">
<item-type>Number</item-type>
<label>Data Sent</label>
<description>Data sent in MB</description>
<state readOnly="true" pattern="%d MB"/>
<config-description-ref uri="systeminfo:channels:mediumpriority"/>
</channel-type>
<channel-type id="dataReceived" advanced="true">
<item-type>Number</item-type>
<label>Data Received</label>
<description>Data received in MB</description>
<state readOnly="true" pattern="%d MB"/>
<config-description-ref uri="systeminfo:channels:mediumpriority"/>
</channel-type>
</thing:thing-descriptions>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="systeminfo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
<!-- This thing represents a computer with single logical storage device, single drive, single display, battery and one
network interface installed. If other configurations are needed feel free to create different thing types. Currently dynamic
channel creation is not supported from the binding. -->
<thing-type id="computer">
<label>Systeminfo</label>
<description>The computer operating system and hardware information</description>
<channel-groups>
<channel-group id="memory" typeId="memoryGroup"/>
<channel-group id="storage" typeId="storageGroup"/>
<channel-group id="sensors" typeId="sensorsGroup"/>
<channel-group id="cpu" typeId="cpuGroup"/>
<!-- This group types are not mandatory for every computer configuration -->
<channel-group id="process" typeId="processGroup"/>
<channel-group id="drive" typeId="driveGroup"/>
<channel-group id="swap" typeId="swapGroup"/>
<channel-group id="display" typeId="displayGroup"/>
<channel-group id="battery" typeId="batteryGroup"/>
<channel-group id="network" typeId="networkGroup"/>
</channel-groups>
<properties>
<property name="CPU Logical Cores">Not available</property>
<property name="CPU Physical Cores">Not available</property>
<property name="OS Manufacturer">Not available</property>
<property name="OS Version">Not available</property>
<property name="OS Family">Not available</property>
</properties>
<config-description-ref uri="thing-type:systeminfo:computerConfig"/>
</thing-type>
</thing:thing-descriptions>