If for some reason HP response fails to properly parse, i.e. `java.lang.NumberFormatException: For input string: "##"` exception is not handled and scheduler is not re-triggered (polling stops).Fixed build warnings. (#13685)
Signed-off-by: Boris Krivonog <boris.krivonog@inova.si>
This commit is contained in:
parent
fe269b127a
commit
248ca1830a
|
@ -26,6 +26,8 @@ import java.util.Map;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.regoheatpump.internal.protocol.RegoConnection;
|
import org.openhab.binding.regoheatpump.internal.protocol.RegoConnection;
|
||||||
import org.openhab.core.library.types.DecimalType;
|
import org.openhab.core.library.types.DecimalType;
|
||||||
import org.openhab.core.library.types.QuantityType;
|
import org.openhab.core.library.types.QuantityType;
|
||||||
|
@ -34,6 +36,7 @@ import org.openhab.core.library.unit.Units;
|
||||||
import org.openhab.core.thing.ChannelUID;
|
import org.openhab.core.thing.ChannelUID;
|
||||||
import org.openhab.core.thing.Thing;
|
import org.openhab.core.thing.Thing;
|
||||||
import org.openhab.core.thing.ThingStatus;
|
import org.openhab.core.thing.ThingStatus;
|
||||||
|
import org.openhab.core.thing.ThingStatusDetail;
|
||||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||||
import org.openhab.core.types.Command;
|
import org.openhab.core.types.Command;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -45,13 +48,14 @@ import org.slf4j.LoggerFactory;
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
abstract class HusdataHandler extends BaseThingHandler {
|
abstract class HusdataHandler extends BaseThingHandler {
|
||||||
|
|
||||||
private static final Map<Integer, String> MAPPINGS;
|
private static final Map<Integer, String> MAPPINGS;
|
||||||
private final Logger logger = LoggerFactory.getLogger(HusdataHandler.class);
|
private final Logger logger = LoggerFactory.getLogger(HusdataHandler.class);
|
||||||
private RegoConnection connection;
|
private @Nullable RegoConnection connection;
|
||||||
private ScheduledFuture<?> scheduledRefreshFuture;
|
private @Nullable ScheduledFuture<?> scheduledRefreshFuture;
|
||||||
private BufferedReader bufferedReader;
|
private @Nullable BufferedReader bufferedReader;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
MAPPINGS = mappings();
|
MAPPINGS = mappings();
|
||||||
|
@ -61,12 +65,18 @@ abstract class HusdataHandler extends BaseThingHandler {
|
||||||
super(thing);
|
super(thing);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract RegoConnection createConnection();
|
protected abstract RegoConnection createConnection() throws IOException;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
bufferedReader = null;
|
bufferedReader = null;
|
||||||
|
|
||||||
|
try {
|
||||||
connection = createConnection();
|
connection = createConnection();
|
||||||
|
} catch (IOException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
updateStatus(ThingStatus.UNKNOWN);
|
updateStatus(ThingStatus.UNKNOWN);
|
||||||
|
|
||||||
|
@ -78,14 +88,16 @@ abstract class HusdataHandler extends BaseThingHandler {
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|
||||||
|
ScheduledFuture<?> scheduledRefreshFuture = this.scheduledRefreshFuture;
|
||||||
|
this.scheduledRefreshFuture = null;
|
||||||
if (scheduledRefreshFuture != null) {
|
if (scheduledRefreshFuture != null) {
|
||||||
scheduledRefreshFuture.cancel(true);
|
scheduledRefreshFuture.cancel(true);
|
||||||
scheduledRefreshFuture = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RegoConnection connection = this.connection;
|
||||||
|
this.connection = null;
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
connection.close();
|
connection.close();
|
||||||
connection = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,8 +124,10 @@ abstract class HusdataHandler extends BaseThingHandler {
|
||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BufferedReader bufferedReader = this.bufferedReader;
|
||||||
if (bufferedReader == null) {
|
if (bufferedReader == null) {
|
||||||
bufferedReader = new BufferedReader(new InputStreamReader(connection.inputStream()));
|
bufferedReader = new BufferedReader(new InputStreamReader(connection.inputStream()));
|
||||||
|
this.bufferedReader = bufferedReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String line = bufferedReader.readLine();
|
final String line = bufferedReader.readLine();
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.handler;
|
package org.openhab.binding.regoheatpump.internal.handler;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.binding.regoheatpump.internal.RegoHeatPumpBindingConstants;
|
import org.openhab.binding.regoheatpump.internal.RegoHeatPumpBindingConstants;
|
||||||
import org.openhab.binding.regoheatpump.internal.protocol.IpRegoConnection;
|
import org.openhab.binding.regoheatpump.internal.protocol.IpRegoConnection;
|
||||||
import org.openhab.binding.regoheatpump.internal.protocol.RegoConnection;
|
import org.openhab.binding.regoheatpump.internal.protocol.RegoConnection;
|
||||||
|
@ -23,6 +24,7 @@ import org.openhab.core.thing.Thing;
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class IpHusdataHandler extends HusdataHandler {
|
public class IpHusdataHandler extends HusdataHandler {
|
||||||
public IpHusdataHandler(Thing thing) {
|
public IpHusdataHandler(Thing thing) {
|
||||||
super(thing);
|
super(thing);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.handler;
|
package org.openhab.binding.regoheatpump.internal.handler;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.binding.regoheatpump.internal.RegoHeatPumpBindingConstants;
|
import org.openhab.binding.regoheatpump.internal.RegoHeatPumpBindingConstants;
|
||||||
import org.openhab.binding.regoheatpump.internal.protocol.IpRegoConnection;
|
import org.openhab.binding.regoheatpump.internal.protocol.IpRegoConnection;
|
||||||
import org.openhab.binding.regoheatpump.internal.protocol.RegoConnection;
|
import org.openhab.binding.regoheatpump.internal.protocol.RegoConnection;
|
||||||
|
@ -23,6 +24,7 @@ import org.openhab.core.thing.Thing;
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class IpRego6xxHeatPumpHandler extends Rego6xxHeatPumpHandler {
|
public class IpRego6xxHeatPumpHandler extends Rego6xxHeatPumpHandler {
|
||||||
public IpRego6xxHeatPumpHandler(Thing thing) {
|
public IpRego6xxHeatPumpHandler(Thing thing) {
|
||||||
super(thing);
|
super(thing);
|
||||||
|
|
|
@ -29,6 +29,8 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.measure.Unit;
|
import javax.measure.Unit;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.regoheatpump.internal.protocol.RegoConnection;
|
import org.openhab.binding.regoheatpump.internal.protocol.RegoConnection;
|
||||||
import org.openhab.binding.regoheatpump.internal.rego6xx.CommandFactory;
|
import org.openhab.binding.regoheatpump.internal.rego6xx.CommandFactory;
|
||||||
import org.openhab.binding.regoheatpump.internal.rego6xx.ErrorLine;
|
import org.openhab.binding.regoheatpump.internal.rego6xx.ErrorLine;
|
||||||
|
@ -60,13 +62,15 @@ import org.slf4j.LoggerFactory;
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
abstract class Rego6xxHeatPumpHandler extends BaseThingHandler {
|
abstract class Rego6xxHeatPumpHandler extends BaseThingHandler {
|
||||||
|
|
||||||
private static final class ChannelDescriptor {
|
private static final class ChannelDescriptor {
|
||||||
private Date lastUpdate;
|
private @Nullable Date lastUpdate;
|
||||||
private byte[] cachedValue;
|
private byte @Nullable [] cachedValue;
|
||||||
|
|
||||||
public byte[] cachedValueIfNotExpired(int refreshTime) {
|
public byte @Nullable [] cachedValueIfNotExpired(int refreshTime) {
|
||||||
|
Date lastUpdate = this.lastUpdate;
|
||||||
if (lastUpdate == null || (lastUpdate.getTime() + refreshTime * 900 < new Date().getTime())) {
|
if (lastUpdate == null || (lastUpdate.getTime() + refreshTime * 900 < new Date().getTime())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -82,23 +86,27 @@ abstract class Rego6xxHeatPumpHandler extends BaseThingHandler {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(Rego6xxHeatPumpHandler.class);
|
private final Logger logger = LoggerFactory.getLogger(Rego6xxHeatPumpHandler.class);
|
||||||
private final Map<String, ChannelDescriptor> channelDescriptors = new HashMap<>();
|
private final Map<String, ChannelDescriptor> channelDescriptors = new HashMap<>();
|
||||||
|
private final RegoRegisterMapper mapper = RegoRegisterMapper.REGO600;
|
||||||
|
private @Nullable RegoConnection connection;
|
||||||
|
private @Nullable ScheduledFuture<?> scheduledRefreshFuture;
|
||||||
private int refreshInterval;
|
private int refreshInterval;
|
||||||
private RegoConnection connection;
|
|
||||||
private RegoRegisterMapper mapper;
|
|
||||||
private ScheduledFuture<?> scheduledRefreshFuture;
|
|
||||||
|
|
||||||
protected Rego6xxHeatPumpHandler(Thing thing) {
|
protected Rego6xxHeatPumpHandler(Thing thing) {
|
||||||
super(thing);
|
super(thing);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract RegoConnection createConnection();
|
protected abstract RegoConnection createConnection() throws IOException;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
mapper = RegoRegisterMapper.REGO600;
|
|
||||||
refreshInterval = ((Number) getConfig().get(REFRESH_INTERVAL)).intValue();
|
refreshInterval = ((Number) getConfig().get(REFRESH_INTERVAL)).intValue();
|
||||||
|
|
||||||
|
try {
|
||||||
connection = createConnection();
|
connection = createConnection();
|
||||||
|
} catch (IOException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
scheduledRefreshFuture = scheduler.scheduleWithFixedDelay(this::refresh, 2, refreshInterval, TimeUnit.SECONDS);
|
scheduledRefreshFuture = scheduler.scheduleWithFixedDelay(this::refresh, 2, refreshInterval, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
@ -109,21 +117,21 @@ abstract class Rego6xxHeatPumpHandler extends BaseThingHandler {
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|
||||||
|
RegoConnection connection = this.connection;
|
||||||
|
this.connection = null;
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
connection.close();
|
connection.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScheduledFuture<?> scheduledRefreshFuture = this.scheduledRefreshFuture;
|
||||||
|
this.scheduledRefreshFuture = null;
|
||||||
if (scheduledRefreshFuture != null) {
|
if (scheduledRefreshFuture != null) {
|
||||||
scheduledRefreshFuture.cancel(true);
|
scheduledRefreshFuture.cancel(true);
|
||||||
scheduledRefreshFuture = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (channelDescriptors) {
|
synchronized (channelDescriptors) {
|
||||||
channelDescriptors.clear();
|
channelDescriptors.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
connection = null;
|
|
||||||
mapper = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -220,7 +228,7 @@ abstract class Rego6xxHeatPumpHandler extends BaseThingHandler {
|
||||||
private void readAndUpdateLastError(String channelIID, Function<ErrorLine, State> converter) {
|
private void readAndUpdateLastError(String channelIID, Function<ErrorLine, State> converter) {
|
||||||
executeCommandAndUpdateState(channelIID, CommandFactory.createReadLastErrorCommand(),
|
executeCommandAndUpdateState(channelIID, CommandFactory.createReadLastErrorCommand(),
|
||||||
ResponseParserFactory.ERROR_LINE, e -> {
|
ResponseParserFactory.ERROR_LINE, e -> {
|
||||||
return e == null ? UnDefType.NULL : converter.apply(e);
|
return e == ErrorLine.NO_ERROR ? UnDefType.NULL : converter.apply(e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,7 +260,7 @@ abstract class Rego6xxHeatPumpHandler extends BaseThingHandler {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized <T> void executeCommand(String channelIID, byte[] command, ResponseParser<T> parser,
|
private synchronized <T> void executeCommand(@Nullable String channelIID, byte[] command, ResponseParser<T> parser,
|
||||||
Consumer<T> resultProcessor) {
|
Consumer<T> resultProcessor) {
|
||||||
try {
|
try {
|
||||||
T result = executeCommandWithRetry(channelIID, command, parser, 5);
|
T result = executeCommandWithRetry(channelIID, command, parser, 5);
|
||||||
|
@ -265,17 +273,19 @@ abstract class Rego6xxHeatPumpHandler extends BaseThingHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||||
} catch (Rego6xxProtocolException e) {
|
} catch (Rego6xxProtocolException | RuntimeException e) {
|
||||||
logger.warn("Executing command for channel '{}' failed.", channelIID, e);
|
logger.warn("Executing command for channel '{}' failed.", channelIID, e);
|
||||||
|
if (channelIID != null) {
|
||||||
updateState(channelIID, UnDefType.UNDEF);
|
updateState(channelIID, UnDefType.UNDEF);
|
||||||
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
logger.debug("Execution interrupted when accessing value for channel '{}'.", channelIID, e);
|
logger.debug("Execution interrupted when accessing value for channel '{}'.", channelIID, e);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T executeCommandWithRetry(String channelIID, byte[] command, ResponseParser<T> parser, int retry)
|
private <T> T executeCommandWithRetry(@Nullable String channelIID, byte[] command, ResponseParser<T> parser,
|
||||||
throws Rego6xxProtocolException, IOException, InterruptedException {
|
int retry) throws Rego6xxProtocolException, IOException, InterruptedException {
|
||||||
try {
|
try {
|
||||||
checkRegoDevice();
|
checkRegoDevice();
|
||||||
return executeCommand(channelIID, command, parser);
|
return executeCommand(channelIID, command, parser);
|
||||||
|
@ -316,11 +326,12 @@ abstract class Rego6xxHeatPumpHandler extends BaseThingHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T executeCommand(String channelIID, byte[] command, ResponseParser<T> parser)
|
private <T> T executeCommand(@Nullable String channelIID, byte[] command, ResponseParser<T> parser)
|
||||||
throws Rego6xxProtocolException, IOException, InterruptedException {
|
throws Rego6xxProtocolException, IOException, InterruptedException {
|
||||||
try {
|
try {
|
||||||
return executeCommandInternal(channelIID, command, parser);
|
return executeCommandInternal(channelIID, command, parser);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
RegoConnection connection = this.connection;
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
connection.close();
|
connection.close();
|
||||||
}
|
}
|
||||||
|
@ -329,7 +340,7 @@ abstract class Rego6xxHeatPumpHandler extends BaseThingHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T executeCommandInternal(String channelIID, byte[] command, ResponseParser<T> parser)
|
private <T> T executeCommandInternal(@Nullable String channelIID, byte[] command, ResponseParser<T> parser)
|
||||||
throws Rego6xxProtocolException, IOException, InterruptedException {
|
throws Rego6xxProtocolException, IOException, InterruptedException {
|
||||||
// CHANNEL_LAST_ERROR_CODE and CHANNEL_LAST_ERROR_TIMESTAMP are read from same
|
// CHANNEL_LAST_ERROR_CODE and CHANNEL_LAST_ERROR_TIMESTAMP are read from same
|
||||||
// register. To prevent accessing same register twice when both channels are linked,
|
// register. To prevent accessing same register twice when both channels are linked,
|
||||||
|
@ -338,8 +349,12 @@ abstract class Rego6xxHeatPumpHandler extends BaseThingHandler {
|
||||||
|| CHANNEL_LAST_ERROR_TIMESTAMP.equals(channelIID)) ? CHANNEL_LAST_ERROR : channelIID;
|
|| CHANNEL_LAST_ERROR_TIMESTAMP.equals(channelIID)) ? CHANNEL_LAST_ERROR : channelIID;
|
||||||
|
|
||||||
// Use transient channel descriptor for null (not cached) channels.
|
// Use transient channel descriptor for null (not cached) channels.
|
||||||
ChannelDescriptor descriptor = channelIID == null ? new ChannelDescriptor()
|
ChannelDescriptor descriptor;
|
||||||
: channelDescriptorForChannel(mappedChannelIID);
|
if (mappedChannelIID == null) {
|
||||||
|
descriptor = new ChannelDescriptor();
|
||||||
|
} else {
|
||||||
|
descriptor = channelDescriptorForChannel(mappedChannelIID);
|
||||||
|
}
|
||||||
|
|
||||||
byte[] cachedValue = descriptor.cachedValueIfNotExpired(refreshInterval);
|
byte[] cachedValue = descriptor.cachedValueIfNotExpired(refreshInterval);
|
||||||
if (cachedValue != null) {
|
if (cachedValue != null) {
|
||||||
|
@ -348,6 +363,11 @@ abstract class Rego6xxHeatPumpHandler extends BaseThingHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send command to device and wait for response.
|
// Send command to device and wait for response.
|
||||||
|
RegoConnection connection = this.connection;
|
||||||
|
if (connection == null) {
|
||||||
|
throw new IOException("Unable to execute command - no connection available");
|
||||||
|
|
||||||
|
}
|
||||||
if (!connection.isConnected()) {
|
if (!connection.isConnected()) {
|
||||||
connection.connect();
|
connection.connect();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.handler;
|
package org.openhab.binding.regoheatpump.internal.handler;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.regoheatpump.internal.RegoHeatPumpBindingConstants;
|
import org.openhab.binding.regoheatpump.internal.RegoHeatPumpBindingConstants;
|
||||||
import org.openhab.binding.regoheatpump.internal.protocol.RegoConnection;
|
import org.openhab.binding.regoheatpump.internal.protocol.RegoConnection;
|
||||||
import org.openhab.binding.regoheatpump.internal.protocol.SerialRegoConnection;
|
import org.openhab.binding.regoheatpump.internal.protocol.SerialRegoConnection;
|
||||||
|
@ -27,9 +31,10 @@ import org.openhab.core.thing.ThingStatusDetail;
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class SerialHusdataHandler extends HusdataHandler {
|
public class SerialHusdataHandler extends HusdataHandler {
|
||||||
private final SerialPortManager serialPortManager;
|
private final SerialPortManager serialPortManager;
|
||||||
private SerialPortIdentifier serialPortIdentifier;
|
private @Nullable SerialPortIdentifier serialPortIdentifier;
|
||||||
|
|
||||||
public SerialHusdataHandler(Thing thing, SerialPortManager serialPortManager) {
|
public SerialHusdataHandler(Thing thing, SerialPortManager serialPortManager) {
|
||||||
super(thing);
|
super(thing);
|
||||||
|
@ -49,7 +54,11 @@ public class SerialHusdataHandler extends HusdataHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RegoConnection createConnection() {
|
protected RegoConnection createConnection() throws IOException {
|
||||||
|
SerialPortIdentifier serialPortIdentifier = this.serialPortIdentifier;
|
||||||
|
if (serialPortIdentifier == null) {
|
||||||
|
throw new IOException("Serial port does not exist");
|
||||||
|
}
|
||||||
return new SerialRegoConnection(serialPortIdentifier, 19200);
|
return new SerialRegoConnection(serialPortIdentifier, 19200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.handler;
|
package org.openhab.binding.regoheatpump.internal.handler;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.regoheatpump.internal.RegoHeatPumpBindingConstants;
|
import org.openhab.binding.regoheatpump.internal.RegoHeatPumpBindingConstants;
|
||||||
import org.openhab.binding.regoheatpump.internal.protocol.RegoConnection;
|
import org.openhab.binding.regoheatpump.internal.protocol.RegoConnection;
|
||||||
import org.openhab.binding.regoheatpump.internal.protocol.SerialRegoConnection;
|
import org.openhab.binding.regoheatpump.internal.protocol.SerialRegoConnection;
|
||||||
|
@ -27,9 +31,10 @@ import org.openhab.core.thing.ThingStatusDetail;
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class SerialRego6xxHeatPumpHandler extends Rego6xxHeatPumpHandler {
|
public class SerialRego6xxHeatPumpHandler extends Rego6xxHeatPumpHandler {
|
||||||
private final SerialPortManager serialPortManager;
|
private final SerialPortManager serialPortManager;
|
||||||
private SerialPortIdentifier serialPortIdentifier;
|
private @Nullable SerialPortIdentifier serialPortIdentifier;
|
||||||
|
|
||||||
public SerialRego6xxHeatPumpHandler(Thing thing, SerialPortManager serialPortManager) {
|
public SerialRego6xxHeatPumpHandler(Thing thing, SerialPortManager serialPortManager) {
|
||||||
super(thing);
|
super(thing);
|
||||||
|
@ -49,7 +54,11 @@ public class SerialRego6xxHeatPumpHandler extends Rego6xxHeatPumpHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RegoConnection createConnection() {
|
protected RegoConnection createConnection() throws IOException {
|
||||||
|
SerialPortIdentifier serialPortIdentifier = this.serialPortIdentifier;
|
||||||
|
if (serialPortIdentifier == null) {
|
||||||
|
throw new IOException("Serial port does not exist");
|
||||||
|
}
|
||||||
return new SerialRegoConnection(serialPortIdentifier, 19200);
|
return new SerialRegoConnection(serialPortIdentifier, 19200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ import java.io.OutputStream;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -26,6 +28,7 @@ import org.slf4j.LoggerFactory;
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class IpRegoConnection implements RegoConnection {
|
public class IpRegoConnection implements RegoConnection {
|
||||||
/**
|
/**
|
||||||
* Connection timeout in milliseconds
|
* Connection timeout in milliseconds
|
||||||
|
@ -40,7 +43,7 @@ public class IpRegoConnection implements RegoConnection {
|
||||||
private final Logger logger = LoggerFactory.getLogger(IpRegoConnection.class);
|
private final Logger logger = LoggerFactory.getLogger(IpRegoConnection.class);
|
||||||
private final String address;
|
private final String address;
|
||||||
private final int port;
|
private final int port;
|
||||||
private Socket clientSocket;
|
private @Nullable Socket clientSocket;
|
||||||
|
|
||||||
public IpRegoConnection(String address, int port) {
|
public IpRegoConnection(String address, int port) {
|
||||||
this.address = address;
|
this.address = address;
|
||||||
|
@ -50,10 +53,12 @@ public class IpRegoConnection implements RegoConnection {
|
||||||
@Override
|
@Override
|
||||||
public void connect() throws IOException {
|
public void connect() throws IOException {
|
||||||
logger.debug("Connecting to '{}', port = {}.", address, port);
|
logger.debug("Connecting to '{}', port = {}.", address, port);
|
||||||
|
Socket clientSocket = this.clientSocket;
|
||||||
if (clientSocket == null) {
|
if (clientSocket == null) {
|
||||||
clientSocket = new Socket();
|
clientSocket = new Socket();
|
||||||
clientSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
|
clientSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
|
||||||
clientSocket.setKeepAlive(true);
|
clientSocket.setKeepAlive(true);
|
||||||
|
this.clientSocket = clientSocket;
|
||||||
}
|
}
|
||||||
clientSocket.connect(new InetSocketAddress(address, port), CONNECTION_TIMEOUT);
|
clientSocket.connect(new InetSocketAddress(address, port), CONNECTION_TIMEOUT);
|
||||||
logger.debug("Connected to '{}', port = {}.", address, port);
|
logger.debug("Connected to '{}', port = {}.", address, port);
|
||||||
|
@ -61,12 +66,15 @@ public class IpRegoConnection implements RegoConnection {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isConnected() {
|
public boolean isConnected() {
|
||||||
|
Socket clientSocket = this.clientSocket;
|
||||||
return clientSocket != null && clientSocket.isConnected();
|
return clientSocket != null && clientSocket.isConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
try {
|
try {
|
||||||
|
Socket clientSocket = this.clientSocket;
|
||||||
|
this.clientSocket = null;
|
||||||
if (clientSocket != null) {
|
if (clientSocket != null) {
|
||||||
clientSocket.close();
|
clientSocket.close();
|
||||||
}
|
}
|
||||||
|
@ -74,17 +82,23 @@ public class IpRegoConnection implements RegoConnection {
|
||||||
// There is really not much we can do here, ignore the error and continue execution.
|
// There is really not much we can do here, ignore the error and continue execution.
|
||||||
logger.warn("Closing socket failed", e);
|
logger.warn("Closing socket failed", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
clientSocket = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OutputStream outputStream() throws IOException {
|
public OutputStream outputStream() throws IOException {
|
||||||
return clientSocket.getOutputStream();
|
return getClientSocket().getOutputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream inputStream() throws IOException {
|
public InputStream inputStream() throws IOException {
|
||||||
return clientSocket.getInputStream();
|
return getClientSocket().getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Socket getClientSocket() throws IOException {
|
||||||
|
Socket clientSocket = this.clientSocket;
|
||||||
|
if (clientSocket == null) {
|
||||||
|
throw new IOException("Socket closed");
|
||||||
|
}
|
||||||
|
return clientSocket;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,14 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link RegoConnection} is responsible for creating connections to clients.
|
* The {@link RegoConnection} is responsible for creating connections to clients.
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public interface RegoConnection {
|
public interface RegoConnection {
|
||||||
/**
|
/**
|
||||||
* Connect to the receiver. Return true if the connection has succeeded or if already connected.
|
* Connect to the receiver. Return true if the connection has succeeded or if already connected.
|
||||||
|
|
|
@ -16,6 +16,8 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.core.io.transport.serial.PortInUseException;
|
import org.openhab.core.io.transport.serial.PortInUseException;
|
||||||
import org.openhab.core.io.transport.serial.SerialPort;
|
import org.openhab.core.io.transport.serial.SerialPort;
|
||||||
import org.openhab.core.io.transport.serial.SerialPortIdentifier;
|
import org.openhab.core.io.transport.serial.SerialPortIdentifier;
|
||||||
|
@ -26,10 +28,11 @@ import org.openhab.core.io.transport.serial.UnsupportedCommOperationException;
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class SerialRegoConnection implements RegoConnection {
|
public class SerialRegoConnection implements RegoConnection {
|
||||||
private final int baudRate;
|
private final int baudRate;
|
||||||
private final String portName;
|
private final String portName;
|
||||||
private SerialPort serialPort;
|
private @Nullable SerialPort serialPort;
|
||||||
private final SerialPortIdentifier serialPortIdentifier;
|
private final SerialPortIdentifier serialPortIdentifier;
|
||||||
|
|
||||||
public SerialRegoConnection(SerialPortIdentifier serialPortIdentifier, int baudRate) {
|
public SerialRegoConnection(SerialPortIdentifier serialPortIdentifier, int baudRate) {
|
||||||
|
@ -41,10 +44,11 @@ public class SerialRegoConnection implements RegoConnection {
|
||||||
@Override
|
@Override
|
||||||
public void connect() throws IOException {
|
public void connect() throws IOException {
|
||||||
try {
|
try {
|
||||||
serialPort = serialPortIdentifier.open(SerialRegoConnection.class.getCanonicalName(), 2000);
|
SerialPort serialPort = serialPortIdentifier.open(SerialRegoConnection.class.getCanonicalName(), 2000);
|
||||||
serialPort.enableReceiveTimeout(100);
|
serialPort.enableReceiveTimeout(100);
|
||||||
serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
|
serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
|
||||||
SerialPort.PARITY_NONE);
|
SerialPort.PARITY_NONE);
|
||||||
|
this.serialPort = serialPort;
|
||||||
} catch (PortInUseException e) {
|
} catch (PortInUseException e) {
|
||||||
throw new IOException("Serial port already used: " + portName, e);
|
throw new IOException("Serial port already used: " + portName, e);
|
||||||
} catch (UnsupportedCommOperationException e) {
|
} catch (UnsupportedCommOperationException e) {
|
||||||
|
@ -59,19 +63,36 @@ public class SerialRegoConnection implements RegoConnection {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
|
SerialPort serialPort = this.serialPort;
|
||||||
|
this.serialPort = null;
|
||||||
if (serialPort != null) {
|
if (serialPort != null) {
|
||||||
serialPort.close();
|
serialPort.close();
|
||||||
serialPort = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OutputStream outputStream() throws IOException {
|
public OutputStream outputStream() throws IOException {
|
||||||
return serialPort.getOutputStream();
|
OutputStream outputStream = getSerialPort().getOutputStream();
|
||||||
|
if (outputStream == null) {
|
||||||
|
throw new IOException("Sending data is not supported");
|
||||||
|
}
|
||||||
|
return outputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream inputStream() throws IOException {
|
public InputStream inputStream() throws IOException {
|
||||||
return serialPort.getInputStream();
|
InputStream inputStream = getSerialPort().getInputStream();
|
||||||
|
if (inputStream == null) {
|
||||||
|
throw new IOException("Receiving data is not supported");
|
||||||
|
}
|
||||||
|
return inputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SerialPort getSerialPort() throws IOException {
|
||||||
|
SerialPort serialPort = this.serialPort;
|
||||||
|
if (serialPort == null) {
|
||||||
|
throw new IOException("Connection closed");
|
||||||
|
}
|
||||||
|
return serialPort;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,14 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link AbstractLongResponseParser} is responsible for parsing long form responses.
|
* The {@link AbstractLongResponseParser} is responsible for parsing long form responses.
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
abstract class AbstractLongResponseParser<T> extends AbstractResponseParser<T> {
|
abstract class AbstractLongResponseParser<T> extends AbstractResponseParser<T> {
|
||||||
@Override
|
@Override
|
||||||
public int responseLength() {
|
public int responseLength() {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.core.util.HexUtils;
|
import org.openhab.core.util.HexUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,6 +21,7 @@ import org.openhab.core.util.HexUtils;
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
abstract class AbstractResponseParser<T> implements ResponseParser<T> {
|
abstract class AbstractResponseParser<T> implements ResponseParser<T> {
|
||||||
private static final byte COMPUTER_ADDRESS = (byte) 0x01;
|
private static final byte COMPUTER_ADDRESS = (byte) 0x01;
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,14 @@ package org.openhab.binding.regoheatpump.internal.rego6xx;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Checksum} is responsible for calculating checksum of given data.
|
* The {@link Checksum} is responsible for calculating checksum of given data.
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
class Checksum {
|
class Checksum {
|
||||||
static byte calculate(byte[]... lists) {
|
static byte calculate(byte[]... lists) {
|
||||||
return Arrays.stream(lists).reduce((byte) 0, Checksum::calculate, (a, b) -> b);
|
return Arrays.stream(lists).reduce((byte) 0, Checksum::calculate, (a, b) -> b);
|
||||||
|
|
|
@ -12,12 +12,15 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link CommandFactory} is responsible for creating different commands that can
|
* The {@link CommandFactory} is responsible for creating different commands that can
|
||||||
* be send to a rego 6xx unit.
|
* be send to a rego 6xx unit.
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class CommandFactory {
|
public class CommandFactory {
|
||||||
private static final byte DEVICE_ADDRESS = (byte) 0x81;
|
private static final byte DEVICE_ADDRESS = (byte) 0x81;
|
||||||
|
|
||||||
|
|
|
@ -15,15 +15,20 @@ package org.openhab.binding.regoheatpump.internal.rego6xx;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link ErrorLine} is responsible for holding information about a single error line.
|
* The {@link ErrorLine} is responsible for holding information about a single error line.
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class ErrorLine {
|
public class ErrorLine {
|
||||||
private final byte error;
|
private final byte error;
|
||||||
private final String timestamp;
|
private final String timestamp;
|
||||||
|
|
||||||
|
public static final ErrorLine NO_ERROR = new ErrorLine((byte) 0, "");
|
||||||
|
|
||||||
public ErrorLine(byte error, String timestamp) {
|
public ErrorLine(byte error, String timestamp) {
|
||||||
this.error = error;
|
this.error = error;
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
|
|
|
@ -12,18 +12,21 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link ErrorLineResponseParser} is responsible for parsing error information (log) entry.
|
* The {@link ErrorLineResponseParser} is responsible for parsing error information (log) entry.
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
class ErrorLineResponseParser extends AbstractLongResponseParser<ErrorLine> {
|
class ErrorLineResponseParser extends AbstractLongResponseParser<ErrorLine> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ErrorLine convert(byte[] responseBytes) {
|
protected ErrorLine convert(byte[] responseBytes) {
|
||||||
// 255 marks no error.
|
// 255 marks no error.
|
||||||
if (responseBytes[1] == (byte) 255) {
|
if (responseBytes[1] == (byte) 255) {
|
||||||
return null;
|
return ErrorLine.NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ErrorLine(ValueConverter.arrayToByte(responseBytes, 1),
|
return new ErrorLine(ValueConverter.arrayToByte(responseBytes, 1),
|
||||||
|
|
|
@ -12,11 +12,14 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Rego6xxProtocolException} is responsible for holding information about an Rego6xx protocol error.
|
* The {@link Rego6xxProtocolException} is responsible for holding information about an Rego6xx protocol error.
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class Rego6xxProtocolException extends Exception {
|
public class Rego6xxProtocolException extends Exception {
|
||||||
|
|
||||||
private static final long serialVersionUID = 7556083982084149686L;
|
private static final long serialVersionUID = 7556083982084149686L;
|
||||||
|
|
|
@ -19,6 +19,8 @@ import java.util.Map;
|
||||||
|
|
||||||
import javax.measure.Unit;
|
import javax.measure.Unit;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.core.library.unit.SIUnits;
|
import org.openhab.core.library.unit.SIUnits;
|
||||||
import org.openhab.core.library.unit.Units;
|
import org.openhab.core.library.unit.Units;
|
||||||
|
|
||||||
|
@ -27,6 +29,7 @@ import org.openhab.core.library.unit.Units;
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class RegoRegisterMapper {
|
public class RegoRegisterMapper {
|
||||||
public static final RegoRegisterMapper REGO600;
|
public static final RegoRegisterMapper REGO600;
|
||||||
|
|
||||||
|
@ -35,7 +38,7 @@ public class RegoRegisterMapper {
|
||||||
|
|
||||||
public double scaleFactor();
|
public double scaleFactor();
|
||||||
|
|
||||||
public Unit<?> unit();
|
public @Nullable Unit<?> unit();
|
||||||
|
|
||||||
public int convertValue(short value);
|
public int convertValue(short value);
|
||||||
}
|
}
|
||||||
|
@ -44,9 +47,9 @@ public class RegoRegisterMapper {
|
||||||
private static class ChannelImpl implements Channel {
|
private static class ChannelImpl implements Channel {
|
||||||
private final short address;
|
private final short address;
|
||||||
private final double scaleFactor;
|
private final double scaleFactor;
|
||||||
private final Unit<?> unit;
|
private @Nullable final Unit<?> unit;
|
||||||
|
|
||||||
private ChannelImpl(short address, double scaleFactor, Unit<?> unit) {
|
private ChannelImpl(short address, double scaleFactor, @Nullable Unit<?> unit) {
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.scaleFactor = scaleFactor;
|
this.scaleFactor = scaleFactor;
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
|
@ -63,7 +66,7 @@ public class RegoRegisterMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Unit<?> unit() {
|
public @Nullable Unit<?> unit() {
|
||||||
return unit;
|
return unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +107,7 @@ public class RegoRegisterMapper {
|
||||||
this.mappings = mappings;
|
this.mappings = mappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Channel map(String channelIID) {
|
public @Nullable Channel map(String channelIID) {
|
||||||
return mappings.get(channelIID);
|
return mappings.get(channelIID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,14 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link ResponseParser} is responsible for parsing arbitrary data coming from a rego 6xx unit.
|
* The {@link ResponseParser} is responsible for parsing arbitrary data coming from a rego 6xx unit.
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public interface ResponseParser<T> {
|
public interface ResponseParser<T> {
|
||||||
public int responseLength();
|
public int responseLength();
|
||||||
|
|
||||||
|
|
|
@ -12,15 +12,18 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link ResponseParserFactory} is responsible for providing parsers for all known data
|
* The {@link ResponseParserFactory} is responsible for providing parsers for all known data
|
||||||
* forms coming from the rego 6xx unit.
|
* forms coming from the rego 6xx unit.
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class ResponseParserFactory {
|
public class ResponseParserFactory {
|
||||||
public static final ResponseParser<Short> SHORT = new ShortResponseParser();
|
public static final ResponseParser<Short> SHORT = new ShortResponseParser();
|
||||||
public static final ResponseParser<String> STRING = new StringResponseParser();
|
public static final ResponseParser<String> STRING = new StringResponseParser();
|
||||||
public static final ResponseParser<ErrorLine> ERROR_LINE = new ErrorLineResponseParser();
|
public static final ResponseParser<ErrorLine> ERROR_LINE = new ErrorLineResponseParser();
|
||||||
public static final ResponseParser<Void> WRITE = new WriteResponse();
|
public static final ResponseParser<String> WRITE = new WriteResponse();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,15 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link ShortResponseParser} is responsible for parsing short form data format
|
* The {@link ShortResponseParser} is responsible for parsing short form data format
|
||||||
* coming from the rego 6xx unit.
|
* coming from the rego 6xx unit.
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
class ShortResponseParser extends AbstractResponseParser<Short> {
|
class ShortResponseParser extends AbstractResponseParser<Short> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -12,12 +12,15 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link StringResponseParser} is responsible for parsing long (text) form data format
|
* The {@link StringResponseParser} is responsible for parsing long (text) form data format
|
||||||
* coming from the rego 6xx unit.
|
* coming from the rego 6xx unit.
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
class StringResponseParser extends AbstractLongResponseParser<String> {
|
class StringResponseParser extends AbstractLongResponseParser<String> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -12,11 +12,14 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link ValueConverter} is responsible for converting various rego 6xx specific data types.
|
* The {@link ValueConverter} is responsible for converting various rego 6xx specific data types.
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
class ValueConverter {
|
class ValueConverter {
|
||||||
public static byte[] shortToSevenBitFormat(short value) {
|
public static byte[] shortToSevenBitFormat(short value) {
|
||||||
byte b1 = (byte) ((value & 0xC000) >> 14);
|
byte b1 = (byte) ((value & 0xC000) >> 14);
|
||||||
|
|
|
@ -12,20 +12,23 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
package org.openhab.binding.regoheatpump.internal.rego6xx;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link WriteResponse} is responsible for parsing write responses
|
* The {@link WriteResponse} is responsible for parsing write responses
|
||||||
* coming from the rego 6xx unit.
|
* coming from the rego 6xx unit.
|
||||||
*
|
*
|
||||||
* @author Boris Krivonog - Initial contribution
|
* @author Boris Krivonog - Initial contribution
|
||||||
*/
|
*/
|
||||||
class WriteResponse extends AbstractResponseParser<Void> {
|
@NonNullByDefault
|
||||||
|
class WriteResponse extends AbstractResponseParser<String> {
|
||||||
@Override
|
@Override
|
||||||
public int responseLength() {
|
public int responseLength() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void convert(byte[] responseBytes) {
|
protected String convert(byte[] responseBytes) {
|
||||||
return null;
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue