diff --git a/CODEOWNERS b/CODEOWNERS index af1309b2b82bf..5dcd99276b4a1 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -47,6 +47,7 @@ /bundles/org.openhab.binding.feican/ @Hilbrand /bundles/org.openhab.binding.folding/ @fa2k /bundles/org.openhab.binding.freebox/ @lolodomo +/bundles/org.openhab.binding.froeling/ @codeworkx /bundles/org.openhab.binding.fronius/ @trokohl /bundles/org.openhab.binding.fsinternetradio/ @paphko /bundles/org.openhab.binding.ftpupload/ @paulianttila diff --git a/bom/openhab-addons/pom.xml b/bom/openhab-addons/pom.xml index 587fb02e1ed25..cca3b54484012 100644 --- a/bom/openhab-addons/pom.xml +++ b/bom/openhab-addons/pom.xml @@ -225,6 +225,11 @@ org.openhab.binding.freebox ${project.version} + + org.openhab.addons.bundles + org.openhab.binding.froeling + ${project.version} + org.openhab.addons.bundles org.openhab.binding.fronius diff --git a/bundles/org.openhab.binding.froeling/.classpath b/bundles/org.openhab.binding.froeling/.classpath new file mode 100644 index 0000000000000..a5d95095ccaaf --- /dev/null +++ b/bundles/org.openhab.binding.froeling/.classpath @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.froeling/.project b/bundles/org.openhab.binding.froeling/.project new file mode 100644 index 0000000000000..50fe70b812a64 --- /dev/null +++ b/bundles/org.openhab.binding.froeling/.project @@ -0,0 +1,23 @@ + + + org.openhab.binding.froeling + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/bundles/org.openhab.binding.froeling/NOTICE b/bundles/org.openhab.binding.froeling/NOTICE new file mode 100644 index 0000000000000..4c20ef446c1e4 --- /dev/null +++ b/bundles/org.openhab.binding.froeling/NOTICE @@ -0,0 +1,13 @@ +This content is produced and maintained by the openHAB project. + +* Project home: https://www.openhab.org + +== Declared Project Licenses + +This program and the accompanying materials are made available under the terms +of the Eclipse Public License 2.0 which is available at +https://www.eclipse.org/legal/epl-2.0/. + +== Source Code + +https://github.com/openhab/openhab2-addons diff --git a/bundles/org.openhab.binding.froeling/README.md b/bundles/org.openhab.binding.froeling/README.md new file mode 100644 index 0000000000000..bdb80d8c46b87 --- /dev/null +++ b/bundles/org.openhab.binding.froeling/README.md @@ -0,0 +1,72 @@ +# Froeling Binding + +The Froeling binding is used for reading data from Froeling furnace controllers. + +## Supported Bridges + +Serial-LAN converter + +## Supported Things + +Froeling P3200 controller (Bridge connected to COM1) + +## Discovery + +Discovery is not implemented. + +## Binding Configuration + +No binding configuration required. + +## Thing Configuration + +The Serial-LAN converter bridge needs ip address and telnet port of the Serial-LAN converter. +The Froeling controller thing needs controller type, COM-port of the Froeling furnace controller and a polling interval. + +## Channels + +* **thing** `froeling` + * **channel** `status` (String) + * **channel** `furnacetemperature-current` (Number) + * **channel** `exhaustgastemperature-current` (Number) + * **channel** `furnacecontrolvariable` (Number) + * **channel** `primaryair` (Number) + * **channel** `remainoxygen` (Number) + * **channel** `oxygencontroller` (Number) + * **channel** `secondaryair` (Number) + * **channel** `idfan-setpoint` (Number) + * **channel** `idfan-current` (Number) + * **channel** `exhaustgastemperature-setpoint` (Number) + * **channel** `slidein-current` (Number) + * **channel** `pellet` (Number) + * **channel** `fillinglevel` (Number) + * **channel** `intakespeed` (Number) + * **channel** `deliverypower` (Number) + * **channel** `sensor-1` (Number) + * **channel** `furnacetemperature-setpoint` (Number) + * **channel** `sensor-buffertop` (Number) + * **channel** `sensor-bufferbottom` (Number) + * **channel** `bufferpump` (Number) + * **channel** `sensor-boiler` (Number) + * **channel** `sensor-flow1` (Number) + * **channel** `sensor-flow2` (Number) + * **channel** `heatingcircuitpump1` (Number) + * **channel** `heatingcircuitpump2` (Number) + * **channel** `outdoortemperature` (Number) + * **channel** `collectortemperature` (Number) + * **channel** `operatinghours` (Number) + * **channel** `error` (String) + * **channel** `lastupdate` (DateTime) + +## Full Example + +Items: +``` +String FROELING_Status "Status: [%s]" (Froeling) { channel="froeling:controller:812d9fcb:status" } +String FROELING_Error "Error: [%s]" (Froeling) { channel="froeling:controller:812d9fcb:error" } +Number FROELING_Exhaustgastemperature "Exhaustgastemperature: [%d °C]" (Froeling) { channel="froeling:controller:812d9fcb:exhaustgastemperature-current" } +Number FROELING_Furnacetemperature "Furnacetemperature: [%d °C]" (Froeling) { channel="froeling:controller:812d9fcb:furnacetemperature-current" } +Number FROELING_Slidein_current "Slidein: [%d %%]" (Froeling) { channel="froeling:controller:812d9fcb:slidein-current" } +DateTime FROELING_Lastupdate "Last update: [%1$tY-%1$tm-%1$td %1$tT]" (Froeling) { channel="froeling:controller:812d9fcb:lastupdate" } +``` +812d9fcb = Controller ID as shown in PaperUI diff --git a/bundles/org.openhab.binding.froeling/pom.xml b/bundles/org.openhab.binding.froeling/pom.xml new file mode 100644 index 0000000000000..922348dc9b7db --- /dev/null +++ b/bundles/org.openhab.binding.froeling/pom.xml @@ -0,0 +1,16 @@ + + + + 4.0.0 + + + org.openhab.addons.bundles + org.openhab.addons.reactor.bundles + 2.5.0-SNAPSHOT + + + org.openhab.binding.froeling + + openHAB Add-ons :: Bundles :: froeling Binding + + diff --git a/bundles/org.openhab.binding.froeling/src/main/feature/feature.xml b/bundles/org.openhab.binding.froeling/src/main/feature/feature.xml new file mode 100644 index 0000000000000..981ca6f1324eb --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/feature/feature.xml @@ -0,0 +1,9 @@ + + + mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${project.version}/xml/features + + + openhab-runtime-base + mvn:org.openhab.addons.bundles/org.openhab.binding.froeling/${project.version} + + diff --git a/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/handler/IPBridgeHandler.java b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/handler/IPBridgeHandler.java new file mode 100644 index 0000000000000..50eb13f17bbb5 --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/handler/IPBridgeHandler.java @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2010-2019 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.froeling.handler; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.lang.StringUtils; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.thing.Bridge; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.ThingStatus; +import org.eclipse.smarthome.core.thing.ThingStatusDetail; +import org.eclipse.smarthome.core.thing.binding.BaseBridgeHandler; +import org.eclipse.smarthome.core.types.Command; +import org.openhab.binding.froeling.internal.config.IPBridgeConfiguration; +import org.openhab.binding.froeling.internal.net.TelnetSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link IPBridgeHandler} is responsible for communicating with + * a Serial-LAN converter. + * + * @author Daniel Hillenbrand - Initial contribution + */ +@NonNullByDefault +public class IPBridgeHandler extends BaseBridgeHandler { + + private Logger logger = LoggerFactory.getLogger(IPBridgeHandler.class); + private TelnetSession session = null; + IPBridgeConfiguration config = getThing().getConfiguration().as(IPBridgeConfiguration.class); + + public IPBridgeHandler(Bridge bridge) { + super(bridge); + this.session = new TelnetSession(); + } + + @Override + public void handleCommand(ChannelUID channelUID, Command command) { + // TODO Auto-generated method stub + + } + + @Override + public void initialize() { + this.scheduler.schedule(new Runnable() { + @Override + public void run() { + updateStatus(ThingStatus.ONLINE); + if (config == null) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "bridge configuration missing"); + return; + } + + if (StringUtils.isEmpty(config.getIpAddress())) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "bridge address not specified"); + return; + } + + if (config.getPort() <= 0) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "bridge port not specified"); + return; + } + } + }, 0, TimeUnit.SECONDS); + } + + public synchronized void connect() { + if (this.session != null) { + if (this.session.isConnected()) { + this.logger.info("Already connected to the bridge"); + return; + } + } else { + this.logger.info("TelnetSession is null, creating new session"); + this.session = new TelnetSession(); + } + this.logger.info("Connecting to bridge at {}:{}", config.getIpAddress(), config.getPort()); + try { + this.session.open(config.getIpAddress(), config.getPort()); + } catch (IOException e) { + this.logger.error("Failed to connect to bridge at {}:{}", config.getIpAddress(), config.getPort()); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "failed to connect"); + } + this.logger.debug("Connected to bridge at {}:{}", config.getIpAddress(), config.getPort()); + updateStatus(ThingStatus.ONLINE); + } + + public boolean isConnected() { + if (this.session != null) { + this.logger.info("Bridge state: {}", this.session.isConnected()); + return this.session.isConnected(); + } else { + return false; + } + } + + public synchronized void disconnect() { + this.logger.info("Disconnecting from bridge"); + try { + if (this.session != null) { + this.session.close(); + } + } catch (Exception e) { + this.logger.error("Error disconnecting from bridge", e); + } + } + + private synchronized void reconnect() { + this.logger.info("Attempting to reconnect to the bridge"); + disconnect(); + connect(); + } + + @Override + public void dispose() { + disconnect(); + } + + public String readInput() throws IOException { + String buffer = ""; + if (this.session != null) { + if (!this.session.isConnected()) { + reconnect(); + } else { + buffer = this.session.readline(); + } + } + return buffer; + } +} diff --git a/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/handler/froelingHandler.java b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/handler/froelingHandler.java new file mode 100644 index 0000000000000..cbe936e2fa7ea --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/handler/froelingHandler.java @@ -0,0 +1,401 @@ +/** + * Copyright (c) 2010-2019 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.froeling.handler; + +import static org.openhab.binding.froeling.internal.froelingBindingConstants.*; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.library.types.DateTimeType; +import org.eclipse.smarthome.core.library.types.DecimalType; +import org.eclipse.smarthome.core.library.types.StringType; +import org.eclipse.smarthome.core.thing.Bridge; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingStatus; +import org.eclipse.smarthome.core.thing.ThingStatusDetail; +import org.eclipse.smarthome.core.thing.binding.BaseThingHandler; +import org.eclipse.smarthome.core.thing.binding.ThingHandler; +import org.eclipse.smarthome.core.types.Command; +import org.openhab.binding.froeling.internal.config.FroelingConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link froelingHandler} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Daniel Hillenbrand - Initial contribution + */ +@NonNullByDefault +public class froelingHandler extends BaseThingHandler { + private final Logger logger = LoggerFactory.getLogger(froelingHandler.class); + private @Nullable FroelingConfiguration config; + private IPBridgeHandler bridgeHandler = null; + + public froelingHandler(Thing thing) { + super(thing); + } + + @Override + public void handleCommand(ChannelUID channelUID, Command command) { + // TODO: handle command + } + + @Override + public void initialize() { + config = getConfigAs(FroelingConfiguration.class); + getIPBridgeHandler(); + + updateStatus(ThingStatus.ONLINE); + PollingSchedularService pSS = new PollingSchedularService(); + try { + this.logger.debug("Entering pollingLoop"); + pSS.pollingLoop(); + } catch (Exception e) { + this.logger.error("Error while polling:", e); + } + } + + @NonNullByDefault + public class PollingSchedularService { + FroelingConfiguration config = getThing().getConfiguration().as(FroelingConfiguration.class); + private Logger logger = LoggerFactory.getLogger(PollingSchedularService.class); + + public void pollingLoop() throws Exception { + long initialDelay = 10; + long pollingInterval = config.getPollingInterval().longValue(); + + if (pollingInterval < 5 || pollingInterval > 3600) { + this.logger.warn("Invalid polling rate: {}. Using 5 seconds.", pollingInterval); + pollingInterval = 5; + } + + this.logger.info("Starting PollingService with interval: {} seconds", pollingInterval); + ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); + executor.scheduleWithFixedDelay(new PollingService(), initialDelay, pollingInterval, TimeUnit.SECONDS); + } + } + + @NonNullByDefault + class PollingService implements Runnable { + @Override + public void run() { + // Get and parse data from froeling controller + getData(); + } + } + + public void getData() { + this.logger.info("Trying to get some data"); + FroelingConfiguration config = null; + try { + config = getThing().getConfiguration().as(FroelingConfiguration.class); + } catch (Exception e) { + this.logger.error("Error getting Froeling configuration"); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "Error getting Froeling configuration"); + return; + } + + switch (config.getControllerType()) { + case "P3200": + this.logger.info("Froeling controller: {} COM-Port: {}", config.getControllerType(), + config.getComPort()); + switch (config.getComPort()) { + case "COM1": + this.logger.info("Case: COM1"); + if (bridgeHandler == null) { + this.logger.error("BridgeHandler not available"); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, + "BridgeHandler not available"); + return; + } + // Connect to bridge + bridgeHandler.connect(); + // Check if bridge is connected and get some data + if (bridgeHandler.isConnected()) { + this.logger.info("BridgeHandler is connected, calling getP3200COM1Data()"); + updateStatus(ThingStatus.ONLINE); + getP3200COM1Data(); + } else { + this.logger.error("BridgeHandler is not connected, not calling getP3200COM1Data()"); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, + "BridgeHandler is not connected"); + return; + } + // Disconnect from bridge + bridgeHandler.disconnect(); + break; + case "COM2": + this.logger.warn("Specified COM-Port not supported yet"); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "Specified COM-Port not supported yet"); + break; + default: + this.logger.error("Invalid COM-Port selected"); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "Invalid COM-Port selected"); + break; + } + break; + default: + this.logger.error("Invalid Froeling controller selected"); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "Invalid Froeling controller selected"); + break; + } + } + + public void getP3200COM1Data() { + this.logger.info("Getting P3200 controller data"); + long timeStart = System.currentTimeMillis(); + boolean dataStart = false; + boolean dataSuccess = false; + int iterations = 0; + String inputData = ""; + String buffer = ""; + String dataBlockSeparator = "$ "; + + // Get data from controller + while (dataSuccess == false) { + try { + inputData = bridgeHandler.readInput(); + if (inputData != null) { + if (dataStart == true && inputData.startsWith(dataBlockSeparator)) { + // Got a full data block + this.logger.info("Got full data block from Froeling controller"); + dataSuccess = true; + break; + } + if (dataStart == false && inputData.startsWith(dataBlockSeparator)) { + dataStart = true; + } + if (dataStart == true && !inputData.isEmpty()) { + buffer += inputData; + } else if (dataStart == true && inputData.isEmpty()) { + buffer += "\r\n"; + } + } + } catch (Exception e) { + this.logger.error("Failed getting data from Froeling controller:", e); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, + "failed getting data from Froeling controller"); + break; + } + if (iterations >= 200) { + this.logger.error("No full data block after 200 iterations."); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, + "No full data block after 200 iterations"); + break; + } + if ((System.currentTimeMillis() - 60000L) > timeStart) { + this.logger.error("No full data block after 60 seconds."); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, + "No full data block after 60 seconds"); + break; + } + iterations += 1; + } + + // Parse data + if (dataSuccess == true) { + this.logger.info("Parsing P3200 controller data"); + try { + String[] lineArray = buffer.split("\r\n"); + + for (String line : lineArray) { + String data[] = line.split(";"); + + /* + * data[0] = Label + * data[1] = Value + * data[2] = Ordinal number + * data[3] = Factor for value + * data[4] = Unit + * data[5] = Unit if data[4] is empty + */ + + // Remove data block separator from status label + if (data[0].startsWith(dataBlockSeparator)) { + data[0] = data[0].replace(dataBlockSeparator, ""); + } + + // Trim label + data[0] = data[0].trim(); + + // Print raw data + // this.logger.info("RAW: (" + data[2] + ") " + data[0] + " = " + data[1] + " " + data[4] + "[" + // + data[3] + "]"); + + // Don't try to convert status and error texts to int + if (!data[2].equals("1") && !data[2].equals("99")) { + int factor = Integer.parseInt(data[3]); + int value = Integer.parseInt(data[1]); + + // induced draft fan + if (data[2].equals("10")) { + data[1] = Integer.toString((value / 30)); + } else { + data[1] = Integer.toString((value / factor)); + } + } + // If data[4] is empty, use data[5] to get unit + if (data[4].equals("") && !data[5].isEmpty()) { + data[4] = data[5]; + } + // Print converted data + this.logger.info("CON: ({}) {} = {} {}", data[2], data[0], data[1], data[4]); + + switch (data[2]) { + case "1": + updateState(thing.getChannel(CHANNEL_STATUS).getUID(), new StringType(data[0])); + break; + + case "2": + updateState(thing.getChannel(CHANNEL_FURNACETEMPERATURE_CURRENT).getUID(), + new DecimalType(data[1])); + break; + case "3": + updateState(thing.getChannel(CHANNEL_EXHAUSTTEMPERATURE_CURRENT).getUID(), + new DecimalType(data[1])); + break; + case "4": + updateState(thing.getChannel(CHANNEL_FURNACECONTROLVARIABLE).getUID(), + new DecimalType(data[1])); + break; + case "5": + updateState(thing.getChannel(CHANNEL_PRIMARYAIR).getUID(), new DecimalType(data[1])); + break; + case "6": + updateState(thing.getChannel(CHANNEL_REMAINOXYGEN).getUID(), new DecimalType(data[1])); + break; + case "7": + updateState(thing.getChannel(CHANNEL_OXYGENCONTROLLER).getUID(), new DecimalType(data[1])); + break; + case "8": + updateState(thing.getChannel(CHANNEL_SECONDARYAIR).getUID(), new DecimalType(data[1])); + break; + case "9": + updateState(thing.getChannel(CHANNEL_IDFAN_SETPOINT).getUID(), new DecimalType(data[1])); + break; + case "10": + updateState(thing.getChannel(CHANNEL_IDFAN_CURRENT).getUID(), new DecimalType(data[1])); + break; + case "11": + updateState(thing.getChannel(CHANNEL_EXHAUSTTEMPERATURE_SETPOINT).getUID(), + new DecimalType(data[1])); + break; + case "12": + updateState(thing.getChannel(CHANNEL_SLIDEIN_CURRENT).getUID(), new DecimalType(data[1])); + break; + case "13": + updateState(thing.getChannel(CHANNEL_PELLET).getUID(), new DecimalType(data[1])); + break; + case "14": + updateState(thing.getChannel(CHANNEL_FILLING_LEVEL).getUID(), new DecimalType(data[1])); + break; + case "15": + updateState(thing.getChannel(CHANNEL_INTAKESPEED).getUID(), new DecimalType(data[1])); + break; + case "16": + updateState(thing.getChannel(CHANNEL_DELIVERYPOWER).getUID(), new DecimalType(data[1])); + break; + case "17": + updateState(thing.getChannel(CHANNEL_SENSOR_1).getUID(), new DecimalType(data[1])); + break; + case "18": + updateState(thing.getChannel(CHANNEL_FURNACETEMPERATURE_SETPOINT).getUID(), + new DecimalType(data[1])); + break; + case "20": + updateState(thing.getChannel(CHANNEL_SENSOR_BUFFERTOP).getUID(), new DecimalType(data[1])); + break; + case "21": + updateState(thing.getChannel(CHANNEL_SENSOR_BUFFERBOTTOM).getUID(), + new DecimalType(data[1])); + break; + case "22": + updateState(thing.getChannel(CHANNEL_BUFFER_PUMP).getUID(), new DecimalType(data[1])); + break; + case "23": + updateState(thing.getChannel(CHANNEL_SENSOR_BOILER).getUID(), new DecimalType(data[1])); + break; + case "24": + updateState(thing.getChannel(CHANNEL_SENSOR_FLOW_1).getUID(), new DecimalType(data[1])); + break; + case "25": + updateState(thing.getChannel(CHANNEL_SENSOR_FLOW_2).getUID(), new DecimalType(data[1])); + break; + case "26": + updateState(thing.getChannel(CHANNEL_HEATINGCIRCUITPUMP_1).getUID(), + new DecimalType(data[1])); + break; + case "27": + updateState(thing.getChannel(CHANNEL_HEATINGCIRCUITPUMP_2).getUID(), + new DecimalType(data[1])); + break; + case "28": + updateState(thing.getChannel(CHANNEL_OUTDOORTEMPERATURE).getUID(), + new DecimalType(data[1])); + break; + case "29": + updateState(thing.getChannel(CHANNEL_COLLECTORTEMPERATURE).getUID(), + new DecimalType(data[1])); + break; + case "30": + updateState(thing.getChannel(CHANNEL_OPERATINGHOURS).getUID(), new DecimalType(data[1])); + break; + case "99": + updateState(thing.getChannel(CHANNEL_ERRORS).getUID(), new StringType(data[1])); + break; + default: + this.logger.warn("No channel available for {} with value {} {}", data[0], data[1], data[4]); + break; + } + } + updateState(thing.getChannel(CHANNEL_LASTUPDATE).getUID(), new DateTimeType()); + } catch (Exception e1) { + this.logger.error("Error while parsing P3200 controller data: {}", e1); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, + "Error while parsing P3200 controller data"); + return; + } + this.logger.info("Done parsing P3200 controller data"); + } + } + + private synchronized IPBridgeHandler getIPBridgeHandler() { + if (this.bridgeHandler == null) { + Bridge bridge = getBridge(); + if (bridge == null) { + logger.error("Required bridge not defined"); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, "Required bridge not defined"); + return null; + } + ThingHandler handler = bridge.getHandler(); + if (handler instanceof IPBridgeHandler) { + this.bridgeHandler = (IPBridgeHandler) handler; + } else { + logger.error("BridgeHandler for bridge {} not available", bridge.getUID()); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, "BridgeHandler not available"); + return null; + } + } + return this.bridgeHandler; + } +} diff --git a/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/config/FroelingConfiguration.java b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/config/FroelingConfiguration.java new file mode 100644 index 0000000000000..507f9b6ff0ea6 --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/config/FroelingConfiguration.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2010-2019 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.froeling.internal.config; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Daniel Hillenbrand - Initial contribution + */ +@NonNullByDefault +public class FroelingConfiguration { + private String controllerType; + private String comPort; + private Integer pollingInterval; + + public String getControllerType() { + return controllerType; + } + + public String getComPort() { + return comPort; + } + + public Integer getPollingInterval() { + return pollingInterval; + } + + public void setControllerType(String controllerType) { + this.controllerType = controllerType; + } + + public void setPort(String comPort) { + this.comPort = comPort; + } + + public void setPollingInterval(Integer pollingInterval) { + this.pollingInterval = pollingInterval; + } +} diff --git a/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/config/IPBridgeConfiguration.java b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/config/IPBridgeConfiguration.java new file mode 100644 index 0000000000000..c220bbdba4461 --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/config/IPBridgeConfiguration.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2010-2019 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.froeling.internal.config; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * @author Daniel Hillenbrand - Initial contribution + */ +@NonNullByDefault +public class IPBridgeConfiguration { + private String ipAddress; + private Integer port; + + public String getIpAddress() { + return ipAddress; + } + + public Integer getPort() { + return port; + } + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } + + public void setPort(Integer port) { + this.port = port; + } +} diff --git a/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/froelingBindingConstants.java b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/froelingBindingConstants.java new file mode 100644 index 0000000000000..628a280169a6d --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/froelingBindingConstants.java @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2010-2019 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.froeling.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.thing.ThingTypeUID; + +/** + * The {@link froelingBindingConstants} class defines common constants, which are + * used across the whole binding. + * + * @author Daniel Hillenbrand - Initial contribution + */ +@NonNullByDefault +public class froelingBindingConstants { + + public static final String BINDING_ID = "froeling"; + + // Bridge Type UIDs + public final static ThingTypeUID THING_TYPE_IPBRIDGE = new ThingTypeUID(BINDING_ID, "ipbridge"); + + // List of all Thing Type UIDs + public final static ThingTypeUID THING_TYPE_CONTROLLER = new ThingTypeUID(BINDING_ID, "controller"); + + // List of all Channel ids + public final static String CHANNEL_STATUS = "status"; + public final static String CHANNEL_FURNACETEMPERATURE_CURRENT = "furnacetemperature-current"; + public final static String CHANNEL_EXHAUSTTEMPERATURE_CURRENT = "exhaustgastemperature-current"; + public final static String CHANNEL_FURNACECONTROLVARIABLE = "furnacecontrolvariable"; + public final static String CHANNEL_PRIMARYAIR = "primaryair"; + public final static String CHANNEL_REMAINOXYGEN = "remainoxygen"; + public final static String CHANNEL_OXYGENCONTROLLER = "oxygencontroller"; + public final static String CHANNEL_SECONDARYAIR = "secondaryair"; + public final static String CHANNEL_IDFAN_SETPOINT = "idfan-setpoint"; + public final static String CHANNEL_IDFAN_CURRENT = "idfan-current"; + public final static String CHANNEL_EXHAUSTTEMPERATURE_SETPOINT = "exhaustgastemperature-setpoint"; + public final static String CHANNEL_SLIDEIN_CURRENT = "slidein-current"; + public final static String CHANNEL_PELLET = "pellet"; + public final static String CHANNEL_FILLING_LEVEL = "fillinglevel"; + public final static String CHANNEL_INTAKESPEED = "intakespeed"; + public final static String CHANNEL_DELIVERYPOWER = "deliverypower"; + public final static String CHANNEL_SENSOR_1 = "sensor-1"; + public final static String CHANNEL_FURNACETEMPERATURE_SETPOINT = "furnacetemperature-setpoint"; + public final static String CHANNEL_SENSOR_BUFFERTOP = "sensor-buffertop"; + public final static String CHANNEL_SENSOR_BUFFERBOTTOM = "sensor-bufferbottom"; + public final static String CHANNEL_BUFFER_PUMP = "bufferpump"; + public final static String CHANNEL_SENSOR_BOILER = "sensor-boiler"; + public final static String CHANNEL_SENSOR_FLOW_1 = "sensor-flow1"; + public final static String CHANNEL_SENSOR_FLOW_2 = "sensor-flow2"; + public final static String CHANNEL_HEATINGCIRCUITPUMP_1 = "heatingcircuitpump1"; + public final static String CHANNEL_HEATINGCIRCUITPUMP_2 = "heatingcircuitpump2"; + public final static String CHANNEL_OUTDOORTEMPERATURE = "outdoortemperature"; + public final static String CHANNEL_COLLECTORTEMPERATURE = "collectortemperature"; + public final static String CHANNEL_OPERATINGHOURS = "operatinghours"; + public final static String CHANNEL_ERRORS = "error"; + public final static String CHANNEL_LASTUPDATE = "lastupdate"; +} diff --git a/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/froelingConfiguration.java b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/froelingConfiguration.java new file mode 100644 index 0000000000000..3fa7c02c4858d --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/froelingConfiguration.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2010-2019 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.froeling.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link froelingConfiguration} class contains fields mapping thing configuration parameters. + * + * @author Daniel Hillenbrand - Initial contribution + */ +@NonNullByDefault +public class froelingConfiguration { + + /** + * Sample configuration parameter. Replace with your own. + */ + public String config1; +} diff --git a/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/froelingHandlerFactory.java b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/froelingHandlerFactory.java new file mode 100644 index 0000000000000..90a2cdc245e08 --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/froelingHandlerFactory.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2010-2019 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.froeling.internal; + +import static org.openhab.binding.froeling.internal.froelingBindingConstants.*; + +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.eclipse.smarthome.core.thing.Bridge; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingTypeUID; +import org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory; +import org.eclipse.smarthome.core.thing.binding.ThingHandler; +import org.eclipse.smarthome.core.thing.binding.ThingHandlerFactory; +import org.openhab.binding.froeling.handler.IPBridgeHandler; +import org.openhab.binding.froeling.handler.froelingHandler; +import org.osgi.service.component.annotations.Component; + +/** + * The {@link froelingHandlerFactory} is responsible for creating things and thing + * handlers. + * + * @author Daniel Hillenbrand - Initial contribution + */ +@NonNullByDefault +@Component(configurationPid = "binding.froeling", service = ThingHandlerFactory.class) +public class froelingHandlerFactory extends BaseThingHandlerFactory { + + public final static Set SUPPORTED_BRIDGE_THING_TYPES_UIDS = Collections + .unmodifiableSet(Stream.of(THING_TYPE_IPBRIDGE).collect(Collectors.toSet())); + + public final static Set SUPPORTED_DEVICE_THING_TYPES_UIDS = Collections + .unmodifiableSet(Stream.of(THING_TYPE_CONTROLLER).collect(Collectors.toSet())); + + private final static Set SUPPORTED_THING_TYPES_UIDS = Collections + .unmodifiableSet(Stream.of(THING_TYPE_IPBRIDGE, THING_TYPE_CONTROLLER).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_TYPE_IPBRIDGE)) { + return new IPBridgeHandler((Bridge) thing); + } else if (thingTypeUID.equals(THING_TYPE_CONTROLLER)) { + return new froelingHandler(thing); + } + + return null; + } +} diff --git a/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/net/NonblockingBufferedReader.java b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/net/NonblockingBufferedReader.java new file mode 100644 index 0000000000000..62ea8624693a9 --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/net/NonblockingBufferedReader.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2010-2019 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.froeling.internal.net; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Daniel Hillenbrand - Initial contribution + */ +@NonNullByDefault +public class NonblockingBufferedReader { + + private Logger logger = LoggerFactory.getLogger(NonblockingBufferedReader.class); + + private final BlockingQueue lines = new LinkedBlockingQueue(); + private volatile boolean closed = false; + private Thread backgroundReaderThread = null; + + public NonblockingBufferedReader(final BufferedReader bufferedReader) { + backgroundReaderThread = new Thread(new Runnable() { + @Override + public void run() { + try { + while (!Thread.interrupted()) { + String line = bufferedReader.readLine(); + if (line == null) { + break; + } + lines.add(line); + } + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + closed = true; + } + } + }); + backgroundReaderThread.setDaemon(true); + backgroundReaderThread.start(); + } + + public String readLine() throws IOException { + try { + return closed && lines.isEmpty() ? null : lines.poll(500L, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + this.logger.error("The BackgroundReaderThread was interrupted!", e); + throw new IOException("The BackgroundReaderThread was interrupted!", e); + } + } + + public void close() { + if (backgroundReaderThread != null) { + backgroundReaderThread.interrupt(); + backgroundReaderThread = null; + } + } +} diff --git a/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/net/TelnetSession.java b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/net/TelnetSession.java new file mode 100644 index 0000000000000..495881efa2444 --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/java/org/openhab/binding/froeling/internal/net/TelnetSession.java @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2010-2019 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.froeling.internal.net; + +import java.io.BufferedReader; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +import org.apache.commons.net.telnet.TelnetClient; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A single telnet session. + * + * @author Allan Tong - Initial contribution + */ +@NonNullByDefault +public class TelnetSession implements Closeable { + + private Logger logger = LoggerFactory.getLogger(TelnetSession.class); + private TelnetClient telnetClient = null; + private NonblockingBufferedReader nbreader = null; + + public TelnetSession() { + this.telnetClient = new TelnetClient(); + } + + public void open(String host, int port) throws IOException { + if (this.telnetClient != null) { + this.telnetClient.connect(host, port); + this.telnetClient.setKeepAlive(true); + + this.nbreader = new NonblockingBufferedReader(new BufferedReader( + new InputStreamReader(this.telnetClient.getInputStream(), StandardCharsets.ISO_8859_1), 1024)); + } + } + + @Override + public void close() throws IOException { + try { + if (this.telnetClient != null) { + if (isConnected()) { + this.telnetClient.setKeepAlive(false); + } + this.telnetClient.disconnect(); + } + } catch (Exception e) { + this.logger.error("Error closing telnetClient", e); + } + } + + public boolean isConnected() { + if (this.telnetClient != null) { + return this.telnetClient.isConnected(); + } else { + return false; + } + } + + public String readline() throws IOException { + String buffer = ""; + + if (this.nbreader != null) { + buffer = this.nbreader.readLine(); + } + return buffer; + } +} diff --git a/bundles/org.openhab.binding.froeling/src/main/resources/ESH-INF/binding/binding.xml b/bundles/org.openhab.binding.froeling/src/main/resources/ESH-INF/binding/binding.xml new file mode 100644 index 0000000000000..676633247c3ef --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/resources/ESH-INF/binding/binding.xml @@ -0,0 +1,10 @@ + + + + froeling Binding + This is the binding for Fröling furnace controllers. + Daniel Hillenbrand + + diff --git a/bundles/org.openhab.binding.froeling/src/main/resources/ESH-INF/i18n/froeling_de_DE.properties b/bundles/org.openhab.binding.froeling/src/main/resources/ESH-INF/i18n/froeling_de_DE.properties new file mode 100644 index 0000000000000..2320e17c685f5 --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/resources/ESH-INF/i18n/froeling_de_DE.properties @@ -0,0 +1,54 @@ +# binding +binding.froeling.name = Fr�ling Heizkessel +binding.froeling.description = Anbindung von Fr�ling Heizkessel mit P3200 Steuerung + +# thing types +thing-type.froeling.ipbridge.label = Seriell-LAN Konverter +thing-type.froeling.ipbridge.description = Seriell-LAN Konverter +thing-type.config.froeling.ipbridge.ipAddress.label = Hostname oder IP +thing-type.config.froeling.ipbridge.ipAddress.description = Hostname oder IP des Seriell-LAN Konverters +thing-type.config.froeling.ipbridge.port.label = Port +thing-type.config.froeling.ipbridge.port.description = Telnet Port des Seriell-LAN Konverters + +thing-type.froeling.controller.label = Fr�ling Steuerung +thing-type.froeling.controller.description = Fr�ling Heizkessel Steuerung +thing-type.config.froeling.controller.controllerType.label = Fr�ling Steuerungstyp +thing-type.config.froeling.controller.controllerType.description = Typ der Fr�ling Steuerung +thing-type.config.froeling.controller.comPort.label = Port +thing-type.config.froeling.controller.comPort.description = COM-Port der Fr�ling Steuerung +thing-type.config.froeling.controller.pollingInterval.label = Abfrageintervall +thing-type.config.froeling.controller.pollingInterval.description = Das Abfrageintervall steuert in welchen Zeitabst�nden Daten von der Fr�ling Steuerung gelesen werden + +# channel types +channel-type.froeling.status.label = Zustand +channel-type.froeling.furnacetemperature.label = Kesseltemperatur +channel-type.froeling.exhaustgastemperature-current.label = Abgastemperatur Ist +channel-type.froeling.furnacecontrolvariable.label = Kesselstellgr��e +channel-type.froeling.primaryair.label = Prim�rluft +channel-type.froeling.remainoxygen.label = Restsauerstoff +channel-type.froeling.oxygencontroller.label = Sauerstoffregler +channel-type.froeling.secondaryair.label = Sekund�rluft +channel-type.froeling.idfan-setpoint.label = Saugzug Soll +channel-type.froeling.idfan-current.label = Saugzug Ist +channel-type.froeling.exhaustgastemperature-setpoint.label = Abgstemperatur Soll +channel-type.froeling.slideincurrent.label = Einschub Ist +channel-type.froeling.pellet.label = Sauerstoffregler Pellet +channel-type.froeling.fillinglevel.label = F�llstand +channel-type.froeling.intakespeed.label = Ansauggeschwindigkeit +channel-type.froeling.deliverypower.label = Strom Austragsystem +channel-type.froeling.sensor-1.label = F�hler 1 +channel-type.froeling.furnacesetpoint.label = Kesseltemperatur Soll +channel-type.froeling.sensor-buffertop.label = Puffer oben +channel-type.froeling.sensor-bufferbottom.label = Puffer unten +channel-type.froeling.bufferpump.label = Pufferpumpe +channel-type.froeling.sensor-boiler.label = Boiler +channel-type.froeling.sensor-flow1.label = Vorlauf 1 +channel-type.froeling.sensor-flow2.label = Vorlauf 2 +channel-type.froeling.heatingcircuitpump1.label = Heizkreispumpe 1 +channel-type.froeling.heatingcircuitpump2.label = Heizkreispumpe 2 +channel-type.froeling.outdoortemperature.label = Aussentemperatur +channel-type.froeling.collectortemperature.label = Kollektortemperatur +channel-type.froeling.operatinghours.label = Betriebsstunden +channel-type.froeling.error.label = Fehler +channel-type.froeling.lastupdate.label = Letzte Aktualisierung + diff --git a/bundles/org.openhab.binding.froeling/src/main/resources/ESH-INF/thing/bridge.xml b/bundles/org.openhab.binding.froeling/src/main/resources/ESH-INF/thing/bridge.xml new file mode 100644 index 0000000000000..80ecf73e972c5 --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/resources/ESH-INF/thing/bridge.xml @@ -0,0 +1,25 @@ + + + + + + Serial-LAN Converter connected to Froeling controller + + + + network-address + + The IP or host name of the converter + + + + The telnet port of the converter + 4002 + + + + + \ No newline at end of file diff --git a/bundles/org.openhab.binding.froeling/src/main/resources/ESH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.froeling/src/main/resources/ESH-INF/thing/thing-types.xml new file mode 100644 index 0000000000000..2048d0df34349 --- /dev/null +++ b/bundles/org.openhab.binding.froeling/src/main/resources/ESH-INF/thing/thing-types.xml @@ -0,0 +1,294 @@ + + + + + + + + + + Froeling Controller + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Type of the Froeling controller + + + + + + + COM-Port of the Froeling Controller + + + + + + + The polling interval controls in which intervals to read data from Froeling controller + 600 + + + + + + + String + + Furnace status + + + + + Number + + Furnace temperature current + Temperature + + + + + Number + + Exhaust temperature current + Temperature + + + + + Number + + Furnace control variable + Text + + + + + Number + + Primary air + + + + + Number + + Remain oxygen + + + + + Number + + Oxygen controller + + + + + Number + + Secondary air + + + + + Number + + ID fan setpoint + + + + + Number + + ID fan current + + + + + Number + + Exhaust temperature setpoint + Temperature + + + + + Number + + Slidein current + + + + + Number + + Pellet + + + + + Number + + Filling level + + + + + Number + + Intake speed + + + + + Number + + Delivery power + + + + + Number + + Sensor 1 + + + + + Number + + Furnacetemperature setpoint + + + + + Number + + Sensor buffer top + + + + + Number + + Sensor buffer bottom + + + + + Number + + Buffer pump + + + + + Number + + Sensor boiler + + + + + Number + + Sensor flow 1 + + + + + Number + + Sensor flow 2 + + + + + Number + + Heating circuit pump 1 + + + + + Number + + Heating circuit pump 2 + + + + + Number + + Outdoor temperature + + + + + Number + + Collector temperature + + + + + Number + + Operating hours + + + + + String + + Error + + + + + DateTime + + Time of last update + + + + diff --git a/bundles/pom.xml b/bundles/pom.xml index 467190139c4e1..f0e20ef2172ec 100644 --- a/bundles/pom.xml +++ b/bundles/pom.xml @@ -82,6 +82,7 @@ org.openhab.binding.feican org.openhab.binding.folding org.openhab.binding.freebox + org.openhab.binding.froeling org.openhab.binding.fronius org.openhab.binding.fsinternetradio org.openhab.binding.ftpupload @@ -170,6 +171,7 @@ org.openhab.binding.pulseaudio org.openhab.binding.pushbullet org.openhab.binding.regoheatpump + org.openhab.binding.resol org.openhab.binding.rfxcom org.openhab.binding.rme org.openhab.binding.robonect