added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -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>
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user