Skip to content

Commit

Permalink
[nibeheatpump] Use serial transport (openhab#7633)
Browse files Browse the repository at this point in the history
Related to openhab#7573

Signed-off-by: Wouter Born <github@maindrain.net>
  • Loading branch information
wborn authored and andrewfg committed Aug 31, 2020
1 parent 573b61e commit ab4defc
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 74 deletions.
4 changes: 0 additions & 4 deletions bundles/org.openhab.binding.nibeheatpump/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,4 @@

<name>openHAB Add-ons :: Bundles :: Nibe Heatpump Binding</name>

<properties>
<bnd.importpackage>gnu.io;version="[3.12,6)"</bnd.importpackage>
</properties>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,48 @@

import static org.openhab.binding.nibeheatpump.internal.NibeHeatPumpBindingConstants.SUPPORTED_THING_TYPES_UIDS;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.ThingTypeUID;
import org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory;
import org.eclipse.smarthome.core.thing.binding.ThingHandler;
import org.eclipse.smarthome.core.thing.binding.ThingHandlerFactory;
import org.eclipse.smarthome.io.transport.serial.SerialPortManager;
import org.openhab.binding.nibeheatpump.internal.handler.NibeHeatPumpHandler;
import org.openhab.binding.nibeheatpump.internal.models.PumpModel;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
* The {@link NibeHeatPumpHandlerFactory} is responsible for creating things and
* thing handlers.
*
* @author Pauli Anttila - Initial contribution
*/
@NonNullByDefault
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.nibeheatpump")
public class NibeHeatPumpHandlerFactory extends BaseThingHandlerFactory {

private final SerialPortManager serialPortManager;

@Activate
public NibeHeatPumpHandlerFactory(final @Reference SerialPortManager serialPortManager) {
this.serialPortManager = serialPortManager;
}

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

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

if (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) {
return new NibeHeatPumpHandler(thing, parsePumpModel(thing));
return new NibeHeatPumpHandler(thing, parsePumpModel(thing), serialPortManager);
}

return null;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@

import org.apache.commons.io.IOUtils;
import org.eclipse.smarthome.core.util.HexUtils;
import org.eclipse.smarthome.io.transport.serial.PortInUseException;
import org.eclipse.smarthome.io.transport.serial.SerialPort;
import org.eclipse.smarthome.io.transport.serial.SerialPortEvent;
import org.eclipse.smarthome.io.transport.serial.SerialPortEventListener;
import org.eclipse.smarthome.io.transport.serial.SerialPortIdentifier;
import org.eclipse.smarthome.io.transport.serial.SerialPortManager;
import org.eclipse.smarthome.io.transport.serial.UnsupportedCommOperationException;
import org.openhab.binding.nibeheatpump.internal.NibeHeatPumpException;
import org.openhab.binding.nibeheatpump.internal.config.NibeHeatPumpConfiguration;
import org.openhab.binding.nibeheatpump.internal.message.MessageFactory;
Expand All @@ -35,14 +42,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;

/**
* Connector for serial port communication.
*
Expand All @@ -55,14 +54,16 @@ public class SerialConnector extends NibeHeatPumpBaseConnector {
private InputStream in;
private OutputStream out;
private SerialPort serialPort;
private final SerialPortManager serialPortManager;
private Thread readerThread;
private NibeHeatPumpConfiguration conf;

private final List<byte[]> readQueue = new ArrayList<>();
private final List<byte[]> writeQueue = new ArrayList<>();

SerialConnector() {
public SerialConnector(SerialPortManager serialPortManager) {
logger.debug("Nibe heatpump Serial Port message listener created");
this.serialPortManager = serialPortManager;
}

@Override
Expand All @@ -73,7 +74,10 @@ public void connect(NibeHeatPumpConfiguration configuration) throws NibeHeatPump

conf = configuration;
try {
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(conf.serialPort);
SerialPortIdentifier portIdentifier = serialPortManager.getIdentifier(conf.serialPort);
if (portIdentifier == null) {
throw new NibeHeatPumpException("Connection failed, no such port: " + conf.serialPort);
}

serialPort = portIdentifier.open(this.getClass().getName(), 2000);
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
Expand All @@ -88,12 +92,10 @@ public void connect(NibeHeatPumpConfiguration configuration) throws NibeHeatPump
if (in.markSupported()) {
in.reset();
}
} catch (NoSuchPortException e) {
throw new NibeHeatPumpException("Connection failed, no such a port", e);
} catch (PortInUseException e) {
throw new NibeHeatPumpException("Connection failed, port in use", e);
throw new NibeHeatPumpException("Connection failed, port in use: " + conf.serialPort, e);
} catch (UnsupportedCommOperationException | IOException e) {
throw new NibeHeatPumpException("Connection failed, reason: {}" + e.getMessage(), e);
throw new NibeHeatPumpException("Connection failed, reason: " + e.getMessage(), e);
}

readQueue.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public class SimulatorConnector extends NibeHeatPumpBaseConnector {

private final Map<Integer, Integer> cache = Collections.synchronizedMap(new HashMap<>());

SimulatorConnector() {
public SimulatorConnector() {
logger.debug("Nibe heatpump Test message listener created");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
*/
package org.openhab.binding.nibeheatpump.internal.handler;

import static org.openhab.binding.nibeheatpump.internal.NibeHeatPumpBindingConstants.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
Expand All @@ -34,17 +36,21 @@
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.ThingTypeUID;
import org.eclipse.smarthome.core.thing.binding.BaseThingHandler;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.core.types.RefreshType;
import org.eclipse.smarthome.core.types.State;
import org.eclipse.smarthome.core.types.UnDefType;
import org.eclipse.smarthome.io.transport.serial.SerialPortManager;
import org.openhab.binding.nibeheatpump.internal.NibeHeatPumpCommandResult;
import org.openhab.binding.nibeheatpump.internal.NibeHeatPumpException;
import org.openhab.binding.nibeheatpump.internal.config.NibeHeatPumpConfiguration;
import org.openhab.binding.nibeheatpump.internal.connection.ConnectorFactory;
import org.openhab.binding.nibeheatpump.internal.connection.NibeHeatPumpConnector;
import org.openhab.binding.nibeheatpump.internal.connection.NibeHeatPumpEventListener;
import org.openhab.binding.nibeheatpump.internal.connection.SerialConnector;
import org.openhab.binding.nibeheatpump.internal.connection.SimulatorConnector;
import org.openhab.binding.nibeheatpump.internal.connection.UDPConnector;
import org.openhab.binding.nibeheatpump.internal.message.ModbusDataReadOutMessage;
import org.openhab.binding.nibeheatpump.internal.message.ModbusReadRequestMessage;
import org.openhab.binding.nibeheatpump.internal.message.ModbusReadResponseMessage;
Expand All @@ -70,6 +76,7 @@ public class NibeHeatPumpHandler extends BaseThingHandler implements NibeHeatPum
private static final int TIMEOUT = 4500;
private final Logger logger = LoggerFactory.getLogger(NibeHeatPumpHandler.class);
private final PumpModel pumpModel;
private final SerialPortManager serialPortManager;
private final List<Integer> itemsToPoll = Collections.synchronizedList(new ArrayList<>());
private final List<Integer> itemsToEnableWrite = new ArrayList<>();
private final Map<Integer, CacheObject> stateMap = Collections.synchronizedMap(new HashMap<>());
Expand Down Expand Up @@ -135,9 +142,28 @@ && getThing().getStatusInfo().getStatus() == ThingStatus.ONLINE) {
private ScheduledFuture<?> pollingJob;
private long lastUpdateTime = 0;

public NibeHeatPumpHandler(Thing thing, PumpModel pumpModel) {
public NibeHeatPumpHandler(Thing thing, PumpModel pumpModel, SerialPortManager serialPortManager) {
super(thing);
this.pumpModel = pumpModel;
this.serialPortManager = serialPortManager;
}

private NibeHeatPumpConnector getConnector() throws NibeHeatPumpException {
ThingTypeUID type = thing.getThingTypeUID();

if (THING_TYPE_F1X45_UDP.equals(type) || THING_TYPE_F1X55_UDP.equals(type) || THING_TYPE_F750_UDP.equals(type)
|| THING_TYPE_F470_UDP.equals(type)) {
return new UDPConnector();
} else if (THING_TYPE_F1X45_SERIAL.equals(type) || THING_TYPE_F1X55_SERIAL.equals(type)
|| THING_TYPE_F750_SERIAL.equals(type) || THING_TYPE_F470_SERIAL.equals(type)) {
return new SerialConnector(serialPortManager);
} else if (THING_TYPE_F1X45_SIMULATOR.equals(type) || THING_TYPE_F1X55_SIMULATOR.equals(type)
|| THING_TYPE_F750_SIMULATOR.equals(type) || THING_TYPE_F470_SIMULATOR.equals(type)) {
return new SimulatorConnector();
}

String description = String.format("Unknown connector type %s", type);
throw new NibeHeatPumpException(description);
}

@Override
Expand Down Expand Up @@ -260,7 +286,7 @@ public void initialize() {

try {
parseWriteEnabledItems();
connector = ConnectorFactory.getConnector(thing.getThingTypeUID());
connector = getConnector();
} catch (IllegalArgumentException | NibeHeatPumpException e) {
String description = String.format("Illegal configuration, %s", e.getMessage());
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, description);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package org.openhab.binding.nibeheatpump.internal.handler;

import static org.junit.Assert.assertEquals;
import static org.mockito.MockitoAnnotations.initMocks;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
Expand All @@ -23,10 +24,12 @@
import org.eclipse.smarthome.core.library.types.OnOffType;
import org.eclipse.smarthome.core.library.types.StringType;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.io.transport.serial.SerialPortManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.Mock;
import org.openhab.binding.nibeheatpump.internal.models.PumpModel;
import org.openhab.binding.nibeheatpump.internal.models.VariableInformation;

Expand All @@ -40,15 +43,15 @@ public class NibeHeatPumpHandlerCommand2NibeTest {
private NibeHeatPumpHandler product; // the class under test
private Method m;
private static String METHOD_NAME = "convertCommandToNibeValue";
private Class[] parameterTypes;
private Class<?>[] parameterTypes;
private Object[] parameters;

private int fCoilAddress;

private Command fCommand;

private int fExpected;

private @Mock SerialPortManager serialPortManager;

@Parameterized.Parameters(name = "{index}: f({0}, {1})={2}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] { { 47028, new DecimalType("-1"), (byte) 0xFF },
Expand All @@ -68,7 +71,9 @@ public NibeHeatPumpHandlerCommand2NibeTest(final int coilAddress, final Command

@Before
public void setUp() throws Exception {
product = new NibeHeatPumpHandler(null, PumpModel.F1X55);
initMocks(this);

product = new NibeHeatPumpHandler(null, PumpModel.F1X55, serialPortManager);
parameterTypes = new Class[2];
parameterTypes[0] = VariableInformation.class;
parameterTypes[1] = Command.class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package org.openhab.binding.nibeheatpump.internal.handler;

import static org.junit.Assert.assertEquals;
import static org.mockito.MockitoAnnotations.initMocks;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
Expand All @@ -21,10 +22,12 @@
import java.util.Collection;

import org.eclipse.smarthome.core.types.State;
import org.eclipse.smarthome.io.transport.serial.SerialPortManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.Mock;
import org.openhab.binding.nibeheatpump.internal.models.PumpModel;
import org.openhab.binding.nibeheatpump.internal.models.VariableInformation;

Expand All @@ -50,6 +53,8 @@ public class NibeHeatPumpHandlerNibe2StateTest {
private String fType;
private String fExpected;

private @Mock SerialPortManager serialPortManager;

@Parameterized.Parameters(name = "{index}: f({0}, {1}, {3})={4}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] { //
Expand Down Expand Up @@ -93,7 +98,9 @@ public NibeHeatPumpHandlerNibe2StateTest(final int coilAddress, final int value,

@Before
public void setUp() throws Exception {
product = new NibeHeatPumpHandler(null, PumpModel.F1X55);
initMocks(this);

product = new NibeHeatPumpHandler(null, PumpModel.F1X55, serialPortManager);
parameterTypes = new Class[3];
parameterTypes[0] = VariableInformation.class;
parameterTypes[1] = int.class;
Expand Down

0 comments on commit ab4defc

Please sign in to comment.