added migrated 2.x add-ons

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

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.binding.logreader-${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-logreader" description="Log Reader Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.logreader/${project.version}</bundle>
</feature>
</features>

View File

@@ -0,0 +1,44 @@
/**
* 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.logreader.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;
/**
* The {@link LogReaderBindingConstants} class defines common constants, which are
* used across the whole binding.
*
* @author Miika Jukka - Initial contribution
*/
@NonNullByDefault
public class LogReaderBindingConstants {
private static final String BINDING_ID = "logreader";
// List of all Thing Type UIDs
public static final ThingTypeUID THING_READER = new ThingTypeUID(BINDING_ID, "reader");
// List of all Channel ids
public static final String CHANNEL_LASTWARNING = "lastWarningEvent";
public static final String CHANNEL_LASTERROR = "lastErrorEvent";
public static final String CHANNEL_LASTCUSTOMEVENT = "lastCustomEvent";
public static final String CHANNEL_WARNINGS = "warningEvents";
public static final String CHANNEL_ERRORS = "errorEvents";
public static final String CHANNEL_CUSTOMEVENTS = "customEvents";
public static final String CHANNEL_LOGROTATED = "logRotated";
public static final String CHANNEL_NEWWARNING = "newWarningEvent";
public static final String CHANNEL_NEWERROR = "newErrorEvent";
public static final String CHANNEL_NEWCUSTOM = "newCustomEvent";
}

View File

@@ -0,0 +1,61 @@
/**
* 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.logreader.internal;
import static org.openhab.binding.logreader.internal.LogReaderBindingConstants.THING_READER;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.logreader.internal.filereader.FileTailer;
import org.openhab.binding.logreader.internal.handler.LogHandler;
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;
/**
* The {@link LogReaderHandlerFactory} is responsible for creating things and thing
* handlers.
*
* @author Miika Jukka - Initial contribution
*/
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.logreader")
@NonNullByDefault
public class LogReaderHandlerFactory extends BaseThingHandlerFactory {
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections
.unmodifiableSet(Stream.of(THING_READER).collect(Collectors.toSet()));
@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_READER)) {
return new LogHandler(thing, new FileTailer());
}
return null;
}
}

View File

@@ -0,0 +1,37 @@
/**
* 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.logreader.internal.config;
/**
* Configuration class for {@link LogReaderBinding} binding.
*
* @author Pauli Anttila - Initial contribution
*/
public class LogReaderConfiguration {
public String filePath;
public int refreshRate;
public String warningPatterns;
public String warningBlacklistingPatterns;
public String errorPatterns;
public String errorBlacklistingPatterns;
public String customPatterns;
public String customBlacklistingPatterns;
@Override
public String toString() {
return "[" + "filePath=" + filePath + ", refreshRate=" + refreshRate + ", warningPatterns=" + warningPatterns
+ ", warningBlacklistingPatterns=" + warningBlacklistingPatterns + ", errorPatterns=" + errorPatterns
+ ", errorBlacklistingPatterns=" + errorBlacklistingPatterns + ", customPatterns=" + customPatterns
+ ", customBlacklistingPatterns=" + customBlacklistingPatterns + "]";
}
}

View File

@@ -0,0 +1,105 @@
/**
* 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.logreader.internal.filereader;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
import org.openhab.binding.logreader.internal.filereader.api.FileReaderListener;
import org.openhab.binding.logreader.internal.filereader.api.LogFileReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Base class for LogFileReader implementations. Implements base functions which are same for all LogFileReaders.
*
* @author Pauli Anttila - Initial contribution
*/
public abstract class AbstractLogFileReader implements LogFileReader {
private final Logger logger = LoggerFactory.getLogger(AbstractLogFileReader.class);
private List<FileReaderListener> fileReaderListeners = new CopyOnWriteArrayList<>();
@Override
public boolean registerListener(FileReaderListener fileReaderListener) {
Objects.requireNonNull(fileReaderListener, "It's not allowed to pass a null FileReaderListener.");
return fileReaderListeners.contains(fileReaderListener) ? false : fileReaderListeners.add(fileReaderListener);
}
@Override
public boolean unregisterListener(FileReaderListener fileReaderListener) {
Objects.requireNonNull(fileReaderListener, "It's not allowed to pass a null FileReaderListener.");
return fileReaderListeners.remove(fileReaderListener);
}
/**
* Send file not found event to all registered listeners.
*
*/
public void sendFileNotFoundToListeners() {
for (FileReaderListener fileReaderListener : fileReaderListeners) {
try {
fileReaderListener.fileNotFound();
} catch (Exception e) {
// catch all exceptions give all handlers a fair chance of handling the messages
logger.debug("An exception occurred while calling the FileReaderListener. ", e);
}
}
}
/**
* Send read log line to all registered listeners.
*
*/
public void sendLineToListeners(String line) {
for (FileReaderListener fileReaderListener : fileReaderListeners) {
try {
fileReaderListener.handle(line);
} catch (Exception e) {
// catch all exceptions give all handlers a fair chance of handling the messages
logger.debug("An exception occurred while calling the FileReaderListener. ", e);
}
}
}
/**
* Send file rotation event to all registered listeners.
*
*/
public void sendFileRotationToListeners() {
for (FileReaderListener fileReaderListener : fileReaderListeners) {
try {
fileReaderListener.fileRotated();
} catch (Exception e) {
// catch all exceptions give all handlers a fair chance of handling the messages
logger.debug("An exception occurred while calling the FileReaderListener. ", e);
}
}
}
/**
* Send exception event to all registered listeners.
*
*/
public void sendExceptionToListeners(Exception e) {
for (FileReaderListener fileReaderListener : fileReaderListeners) {
try {
fileReaderListener.handle(e);
} catch (Exception ex) {
// catch all exceptions give all handlers a fair chance of handling the messages
logger.debug("An exception occurred while calling the FileReaderListener. ", ex);
}
}
}
}

View File

@@ -0,0 +1,87 @@
/**
* 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.logreader.internal.filereader;
import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.io.input.Tailer;
import org.apache.commons.io.input.TailerListener;
import org.apache.commons.io.input.TailerListenerAdapter;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.logreader.internal.filereader.api.FileReaderException;
import org.openhab.binding.logreader.internal.filereader.api.LogFileReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Apache Tailer based log file reader implementation.
*
* @author Pauli Anttila - Initial contribution
*/
public class FileTailer extends AbstractLogFileReader implements LogFileReader {
private final Logger logger = LoggerFactory.getLogger(FileTailer.class);
private Tailer tailer;
private ExecutorService executor;
TailerListener logListener = new TailerListenerAdapter() {
@Override
public void handle(@Nullable String line) {
sendLineToListeners(line);
}
@Override
public void fileNotFound() {
sendFileNotFoundToListeners();
}
@Override
public void handle(@Nullable Exception e) {
sendExceptionToListeners(e);
}
@Override
public void fileRotated() {
sendFileRotationToListeners();
}
};
@Override
public void start(String filePath, long refreshRate) throws FileReaderException {
tailer = new Tailer(new File(filePath), logListener, refreshRate, true, false, true);
executor = Executors.newSingleThreadExecutor();
try {
logger.debug("Start executor");
executor.execute(tailer);
logger.debug("Executor started");
} catch (Exception e) {
throw new FileReaderException(e);
}
}
@Override
public void stop() {
logger.debug("Shutdown");
if (tailer != null) {
tailer.stop();
}
if (executor != null) {
executor.shutdown();
}
logger.debug("Shutdown complite");
}
}

View File

@@ -0,0 +1,30 @@
/**
* 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.logreader.internal.filereader.api;
/**
* Exception for file reader errors.
*
* @author Pauli Anttila - Initial contribution
*/
public class FileReaderException extends Exception {
private static final long serialVersionUID = 1272957002073978608L;
public FileReaderException(String message) {
super(message);
}
public FileReaderException(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,46 @@
/**
* 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.logreader.internal.filereader.api;
/**
* Interface for file reader listeners.
*
* @author Pauli Anttila - Initial contribution
*/
public interface FileReaderListener {
/**
* This method is called if the file is not found.
*/
void fileNotFound();
/**
* This method is called if a file rotation is detected.
*
*/
void fileRotated();
/**
* This method is called when new line is detected.
*
* @param line the line.
*/
void handle(String line);
/**
* This method is called when exception has occurred.
*
* @param ex the exception.
*/
void handle(Exception ex);
}

View File

@@ -0,0 +1,51 @@
/**
* 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.logreader.internal.filereader.api;
/**
* Interface for log file readers.
*
* @author Pauli Anttila - Initial contribution
*/
public interface LogFileReader {
/**
* Register listener.
*
* @param fileReaderListener callback implementation to register.
* @return true if registering successfully done.
*/
boolean registerListener(FileReaderListener fileReaderListener);
/**
* Unregister listener.
*
* @param fileReaderListener callback implementation to unregister.
* @return true if unregistering successfully done.
*/
boolean unregisterListener(FileReaderListener fileReaderListener);
/**
* Start log file reader.
*
* @param filePath file to read.
* @param refreshRate how often file is read.
* @throws FileReaderException
*/
void start(String filePath, long refreshRate) throws FileReaderException;
/**
* Stop log file reader.
*/
void stop();
}

View File

@@ -0,0 +1,201 @@
/**
* 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.logreader.internal.handler;
import static org.openhab.binding.logreader.internal.LogReaderBindingConstants.*;
import java.time.ZonedDateTime;
import java.util.regex.PatternSyntaxException;
import org.openhab.binding.logreader.internal.config.LogReaderConfiguration;
import org.openhab.binding.logreader.internal.filereader.api.FileReaderListener;
import org.openhab.binding.logreader.internal.filereader.api.LogFileReader;
import org.openhab.binding.logreader.internal.searchengine.SearchEngine;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.StringType;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link LogReaderHandler} is responsible for handling commands, which are
* sent to one of the channels.
*
* @author Miika Jukka - Initial contribution
* @author Pauli Anttila - Rewrite
*/
public class LogHandler extends BaseThingHandler implements FileReaderListener {
private final Logger logger = LoggerFactory.getLogger(LogHandler.class);
private LogReaderConfiguration configuration;
private LogFileReader fileReader;
private SearchEngine errorEngine;
private SearchEngine warningEngine;
private SearchEngine customEngine;
public LogHandler(Thing thing, LogFileReader fileReader) {
super(thing);
this.fileReader = fileReader;
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
switch (channelUID.getId()) {
case CHANNEL_ERRORS:
updateChannel(channelUID, command, errorEngine);
break;
case CHANNEL_WARNINGS:
updateChannel(channelUID, command, warningEngine);
break;
case CHANNEL_CUSTOMEVENTS:
updateChannel(channelUID, command, customEngine);
break;
default:
logger.debug("Unsupported command '{}' received for channel '{}'", command, channelUID);
}
}
@Override
public void initialize() {
configuration = getConfigAs(LogReaderConfiguration.class);
configuration.filePath = configuration.filePath.replaceFirst("\\$\\{OPENHAB_LOGDIR\\}",
System.getProperty("openhab.logdir"));
logger.debug("Using configuration: {}", configuration);
clearCounters();
try {
warningEngine = new SearchEngine(configuration.warningPatterns, configuration.warningBlacklistingPatterns);
errorEngine = new SearchEngine(configuration.errorPatterns, configuration.errorBlacklistingPatterns);
customEngine = new SearchEngine(configuration.customPatterns, configuration.customBlacklistingPatterns);
} catch (PatternSyntaxException e) {
logger.debug("Illegal search pattern syntax '{}'. ", e.getMessage(), e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, e.getMessage());
return;
}
logger.debug("Start file reader");
try {
fileReader.registerListener(this);
fileReader.start(configuration.filePath, configuration.refreshRate);
updateStatus(ThingStatus.ONLINE);
} catch (Exception e) {
logger.debug("Exception occurred during initalization: {}. ", e.getMessage(), e);
shutdown();
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, e.getMessage());
}
}
@Override
public void dispose() {
logger.debug("Stopping thing");
shutdown();
}
private void updateChannel(ChannelUID channelUID, Command command, SearchEngine matcher) {
if (command instanceof DecimalType) {
matcher.setMatchCount(((DecimalType) command).longValue());
} else if (command instanceof RefreshType) {
updateState(channelUID.getId(), new DecimalType(matcher.getMatchCount()));
} else {
logger.debug("Unsupported command '{}' received for channel '{}'", command, channelUID);
}
}
private void clearCounters() {
if (errorEngine != null) {
errorEngine.clearMatchCount();
}
if (warningEngine != null) {
warningEngine.clearMatchCount();
}
if (customEngine != null) {
customEngine.clearMatchCount();
}
}
private void updateChannelIfLinked(String channelID, State state) {
if (isLinked(channelID)) {
updateState(channelID, state);
}
}
private void shutdown() {
logger.debug("Stop file reader");
fileReader.unregisterListener(this);
fileReader.stop();
}
@Override
public void fileNotFound() {
final String msg = String.format("Log file '%s' does not exist", configuration.filePath);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, msg);
}
@Override
public void fileRotated() {
logger.debug("Log rotated");
updateChannelIfLinked(CHANNEL_LOGROTATED, new DateTimeType(ZonedDateTime.now()));
}
@Override
public void handle(String line) {
if (line == null) {
return;
}
if (!(thing.getStatus() == ThingStatus.ONLINE)) {
updateStatus(ThingStatus.ONLINE);
}
if (errorEngine.isMatching(line)) {
updateChannelIfLinked(CHANNEL_ERRORS, new DecimalType(errorEngine.getMatchCount()));
updateChannelIfLinked(CHANNEL_LASTERROR, new StringType(line));
triggerChannel(CHANNEL_NEWERROR, line);
}
if (warningEngine.isMatching(line)) {
updateChannelIfLinked(CHANNEL_WARNINGS, new DecimalType(warningEngine.getMatchCount()));
updateChannelIfLinked(CHANNEL_LASTWARNING, new StringType(line));
triggerChannel(CHANNEL_NEWWARNING, line);
}
if (customEngine.isMatching(line)) {
updateChannelIfLinked(CHANNEL_CUSTOMEVENTS, new DecimalType(customEngine.getMatchCount()));
updateChannelIfLinked(CHANNEL_LASTCUSTOMEVENT, new StringType(line));
triggerChannel(CHANNEL_NEWCUSTOM, line);
}
}
@Override
public void handle(Exception ex) {
final String msg = ex != null ? ex.getMessage() : "";
logger.debug("Error while trying to read log file: {}. ", msg, ex);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, msg);
}
}

View File

@@ -0,0 +1,110 @@
/**
* 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.logreader.internal.searchengine;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.eclipse.jdt.annotation.Nullable;
/**
* This class implements logic for regular expression based searching.
*
* @author Pauli Anttila - Initial contribution
*/
public class SearchEngine {
private List<Pattern> matchers;
private List<Pattern> blacklistingMatchers;
private long matchCount;
/**
* Initialize search patterns.
*
* @param patterns search patterns.
* @param blacklistingPatterns search patterns to bypass results which have found by the initial search patterns.
*
*/
public SearchEngine(String patterns, String blacklistingPatterns) throws PatternSyntaxException {
matchers = compilePatterns(patterns);
blacklistingMatchers = compilePatterns(blacklistingPatterns);
}
/**
* Check if data is matching to one of the provided search patterns.
*
* @param data data against search will be done.
* @return true if one of the search patterns found.
*/
public boolean isMatching(String data) {
if (isMatching(matchers, data)) {
if (notBlacklisted(data)) {
matchCount++;
return true;
}
}
return false;
}
public long getMatchCount() {
return matchCount;
}
public void setMatchCount(long matchCount) {
this.matchCount = matchCount;
}
public void clearMatchCount() {
setMatchCount(0);
}
/**
* Split pattern string and precompile search patterns.
*
* @param patterns patterns which will handled.
* @return list of precompiled patterns. If pattern parameter is null, empty list is returned.
*/
private List<Pattern> compilePatterns(@Nullable String patterns) throws PatternSyntaxException {
List<Pattern> patternsList = new ArrayList<>();
if (patterns != null && !patterns.isEmpty()) {
String list[] = patterns.split("\\|");
if (list.length > 0) {
for (String patternStr : list) {
patternsList.add(Pattern.compile(patternStr));
}
}
}
return patternsList;
}
private boolean notBlacklisted(String data) {
return !isMatching(blacklistingMatchers, data);
}
private boolean isMatching(@Nullable List<Pattern> patterns, String data) {
if (patterns != null) {
for (Pattern pattern : patterns) {
Matcher matcher = pattern.matcher(data);
if (matcher.find()) {
return true;
}
}
}
return false;
}
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<binding:binding id="logreader" 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>LogReader Binding</name>
<description>Binding that reads through log files and searches e.g. errors and warnings</description>
<author>Pauli Anttila, Miika Jukka</author>
</binding:binding>

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="logreader"
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">
<channel-type id="lastErrorEvent">
<item-type>String</item-type>
<label>Last Error Event</label>
<description>Displays contents of last [ERROR] event</description>
<state readOnly="true"></state>
</channel-type>
<channel-type id="lastWarningEvent">
<item-type>String</item-type>
<label>Last Warning Event</label>
<description>Displays contents of last [WARN] event</description>
<state readOnly="true"></state>
</channel-type>
<channel-type id="lastCustomEvent" advanced="true">
<item-type>String</item-type>
<label>Last Custom Event</label>
<description>Displays contents of last custom event</description>
<state readOnly="true"></state>
</channel-type>
<channel-type id="warningEvents">
<item-type>Number</item-type>
<label>Warning Events Matched</label>
<description>Displays number of [WARN] lines matched to search pattern</description>
</channel-type>
<channel-type id="errorEvents">
<item-type>Number</item-type>
<label>Error Events Matched</label>
<description>Displays number of [ERROR] lines matched to search pattern</description>
</channel-type>
<channel-type id="customEvents" advanced="true">
<item-type>Number</item-type>
<label>Custom Events Matched</label>
<description>Displays number of custom lines matched to search pattern</description>
</channel-type>
<channel-type id="logRotated" advanced="true">
<item-type>DateTime</item-type>
<label>Log Rotated</label>
<description>Last time when log rotated recognized</description>
<state readOnly="true"></state>
</channel-type>
<channel-type id="newErrorEvent">
<kind>trigger</kind>
<label>New Error Event</label>
<description>Fires when a new [ERROR] appears in the log</description>
<event>
</event>
</channel-type>
<channel-type id="newWarningEvent">
<kind>trigger</kind>
<label>New Warning Event</label>
<description>Fires when a new [WARN] appears in the log</description>
<event>
</event>
</channel-type>
<channel-type id="newCustomEvent" advanced="true">
<kind>trigger</kind>
<label>New Custom Event</label>
<description>Fires when a new [CUSTOM] appears in the log</description>
<event>
</event>
</channel-type>
</thing:thing-descriptions>

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="logreader"
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">
<thing-type id="reader">
<label>LogReader</label>
<description>Log reader to analyze log events</description>
<channels>
<channel typeId="lastWarningEvent" id="lastWarningEvent"/>
<channel typeId="lastErrorEvent" id="lastErrorEvent"/>
<channel typeId="lastCustomEvent" id="lastCustomEvent"/>
<channel typeId="warningEvents" id="warningEvents"/>
<channel typeId="errorEvents" id="errorEvents"/>
<channel typeId="customEvents" id="customEvents"/>
<channel typeId="logRotated" id="logRotated"/>
<channel typeId="newWarningEvent" id="newWarningEvent"/>
<channel typeId="newErrorEvent" id="newErrorEvent"/>
<channel typeId="newCustomEvent" id="newCustomEvent"/>
</channels>
<config-description>
<parameter name="filePath" type="text" required="true">
<label>Log File Path</label>
<description>Path to log file. Empty will default to ${OPENHAB_LOGDIR}/openhab.log</description>
<default>${OPENHAB_LOGDIR}/openhab.log</default>
</parameter>
<parameter name="refreshRate" type="integer" required="false">
<label>Refresh Rate</label>
<description>Refresh rate in milliseconds for reading logs</description>
<default>1000</default>
</parameter>
<parameter name="errorPatterns" type="text" required="false">
<label>Error Patterns</label>
<description>Search patterns separated by | character for error events. Empty will default to ERROR+</description>
<default>ERROR+</default>
</parameter>
<parameter name="errorBlacklistingPatterns" type="text" required="false">
<label>Error Blacklisting Patterns</label>
<description>Search patterns for blacklisting unwanted error events separated by | character. </description>
</parameter>
<parameter name="warningPatterns" type="text" required="false">
<label>Warning Patterns</label>
<description>Search patterns separated by | character for warning events. Empty will default to WARN+</description>
<default>WARN+</default>
</parameter>
<parameter name="warningBlacklistingPatterns" type="text" required="false">
<label>Warning Blacklisting Patterns</label>
<description>Search patterns for blacklisting unwanted warning events separated by | character.</description>
</parameter>
<parameter name="customPatterns" type="text" required="false">
<label>Custom Patterns</label>
<description>Search patterns separated by | character for custom events.</description>
</parameter>
<parameter name="customBlacklistingPatterns" type="text" required="false">
<label>Custom Blacklisting Patterns</label>
<description>Search patterns for blacklisting unwanted custom events separated by | character.</description>
</parameter>
</config-description>
</thing-type>
</thing:thing-descriptions>