From 5d5790871413074ffd6fd6b6012d652f0a654f6f Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sat, 16 Oct 2021 16:37:23 +0200 Subject: [PATCH] [sonyprojector] Allow translation of exception messages that can be displayed in MainUI Signed-off-by: Laurent Garnier --- .../internal/SonyProjectorException.java | 13 ++- .../internal/SonyProjectorHandlerFactory.java | 8 +- .../communication/SonyProjectorConnector.java | 83 +++++++++---------- .../sdcp/SonyProjectorSdcpConnector.java | 37 +++++---- .../sdcp/SonyProjectorSdcpError.java | 8 +- .../sdcp/SonyProjectorSdcpSimuConnector.java | 7 +- .../serial/SonyProjectorSerialConnector.java | 47 ++++------- .../serial/SonyProjectorSerialError.java | 8 +- .../SonyProjectorSerialOverIpConnector.java | 16 ++-- .../SonyProjectorSerialSimuConnector.java | 7 +- .../handler/SonyProjectorHandler.java | 38 +++++---- .../OH-INF/i18n/sonyprojector.properties | 7 ++ .../OH-INF/i18n/sonyprojector_fr.properties | 7 ++ 13 files changed, 149 insertions(+), 137 deletions(-) diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorException.java b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorException.java index 6743dd761a595..8d30601f7aaf1 100644 --- a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorException.java +++ b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorException.java @@ -13,7 +13,6 @@ package org.openhab.binding.sonyprojector.internal; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; /** * The {@link SonyProjectorException} class is used for any exception thrown by the binding @@ -21,15 +20,15 @@ * @author Markus Wehrle - Initial contribution */ @NonNullByDefault -public class SonyProjectorException extends Exception { +public class SonyProjectorException extends RuntimeException { + private static final long serialVersionUID = 1L; - // Parameterless Constructor - public SonyProjectorException() { + public SonyProjectorException(String message) { + super(message); } - // Constructor that accepts a message - public SonyProjectorException(@Nullable String message) { - super(message); + public SonyProjectorException(String message, Throwable cause) { + super(message, cause); } } diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorHandlerFactory.java b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorHandlerFactory.java index ad85245fcf886..c830dec372164 100644 --- a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorHandlerFactory.java +++ b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorHandlerFactory.java @@ -22,6 +22,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.sonyprojector.internal.handler.SonyProjectorHandler; +import org.openhab.core.i18n.TranslationProvider; import org.openhab.core.io.transport.serial.SerialPortManager; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingTypeUID; @@ -49,12 +50,15 @@ public class SonyProjectorHandlerFactory extends BaseThingHandlerFactory { private final SerialPortManager serialPortManager; private final SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider; + private final TranslationProvider i18nProvider; @Activate public SonyProjectorHandlerFactory(final @Reference SerialPortManager serialPortManager, - final @Reference SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider) { + final @Reference SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider, + final @Reference TranslationProvider i18nProvider) { this.serialPortManager = serialPortManager; this.stateDescriptionProvider = stateDescriptionProvider; + this.i18nProvider = i18nProvider; } @Override @@ -67,7 +71,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); if (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) { - return new SonyProjectorHandler(thing, stateDescriptionProvider, serialPortManager); + return new SonyProjectorHandler(thing, stateDescriptionProvider, serialPortManager, i18nProvider); } return null; diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/SonyProjectorConnector.java b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/SonyProjectorConnector.java index c319217ade22a..254a4f255cec3 100644 --- a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/SonyProjectorConnector.java +++ b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/SonyProjectorConnector.java @@ -21,6 +21,8 @@ import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.sonyprojector.internal.SonyProjectorException; import org.openhab.binding.sonyprojector.internal.SonyProjectorModel; +import org.openhab.core.i18n.CommunicationException; +import org.openhab.core.i18n.ConnectionException; import org.openhab.core.library.types.OnOffType; import org.openhab.core.util.HexUtils; import org.slf4j.Logger; @@ -897,9 +899,8 @@ protected byte[] getSetting(SonyProjectorItem item) throws SonyProjectorExceptio logger.debug("Get setting {} succeeded: result data: {}", item.getName(), HexUtils.bytesToHex(result)); return result; - } catch (SonyProjectorException e) { - logger.debug("Get setting {} failed: {}", item.getName(), e.getMessage()); - throw new SonyProjectorException("Get setting " + item.getName() + " failed: " + e.getMessage()); + } catch (CommunicationException e) { + throw new SonyProjectorException("Get setting " + item.getName() + " failed", e); } } @@ -916,9 +917,8 @@ private void setSetting(SonyProjectorItem item, byte[] data) throws SonyProjecto try { executeCommand(item, false, data); - } catch (SonyProjectorException e) { - logger.debug("Set setting {} failed: {}", item.getName(), e.getMessage()); - throw new SonyProjectorException("Set setting " + item.getName() + " failed: " + e.getMessage()); + } catch (CommunicationException e) { + throw new SonyProjectorException("Set setting " + item.getName() + " failed", e); } logger.debug("Set setting {} succeeded", item.getName()); @@ -950,13 +950,11 @@ private synchronized void sendIR(SonyProjectorItem item) throws SonyProjectorExc if (!runningSession) { close(); } - } catch (SonyProjectorException e) { - logger.debug("Send IR {} failed: {}", item.getName(), e.getMessage()); - throw new SonyProjectorException("Send IR " + item.getName() + " failed: " + e.getMessage()); + } catch (CommunicationException e) { + throw new SonyProjectorException("Send IR " + item.getName() + " failed", e); } catch (InterruptedException e) { - logger.debug("Send IR {} interrupted: {}", item.getName(), e.getMessage()); Thread.currentThread().interrupt(); - throw new SonyProjectorException("Send IR " + item.getName() + " interrupted: " + e.getMessage()); + throw new SonyProjectorException("Send IR " + item.getName() + " interrupted", e); } logger.debug("Send IR {} succeeded", item.getName()); @@ -971,40 +969,37 @@ private synchronized void sendIR(SonyProjectorItem item) throws SonyProjectorExc * * @return the buffer containing the returned message * - * @throws SonyProjectorException - In case of any problem + * @throws ConnectionException - In case of any connection problem + * @throws CommunicationException - In case of any communication problem */ private synchronized byte[] executeCommand(SonyProjectorItem item, boolean getCommand, byte[] data) - throws SonyProjectorException { - try { - boolean runningSession = connected; + throws ConnectionException, CommunicationException { + boolean runningSession = connected; - open(); + open(); - // Build the message and send it - writeCommand(buildMessage(item, getCommand, data)); + // Build the message and send it + writeCommand(buildMessage(item, getCommand, data)); - // Read the response - byte[] responseMessage = readResponse(); + // Read the response + byte[] responseMessage = readResponse(); - if (!runningSession) { - close(); - } + if (!runningSession) { + close(); + } - // Validate the content of the response - validateResponse(responseMessage, item); + // Validate the content of the response + validateResponse(responseMessage, item); - return responseMessage; - } catch (SonyProjectorException e) { - throw new SonyProjectorException(e.getMessage()); - } + return responseMessage; } /** * Open the connection with the projector if not yet opened * - * @throws SonyProjectorException - In case of any problem + * @throws ConnectionException - In case of any problem */ - public abstract void open() throws SonyProjectorException; + public abstract void open() throws ConnectionException; /** * Close the connection with the projector @@ -1049,23 +1044,23 @@ public void close() { * @param dataBuffer the buffer into which the data is read. * @return the total number of bytes read into the buffer, or -1 if there is no more data because the end of the * stream has been reached. - * @throws SonyProjectorException - If the input stream is null, if the first byte cannot be read for any reason + * @throws CommunicationException - If the input stream is null, if the first byte cannot be read for any reason * other than the end of the file, if the input stream has been closed, or if some other I/O error * occurs. */ - protected int readInput(byte[] dataBuffer) throws SonyProjectorException { + protected int readInput(byte[] dataBuffer) throws CommunicationException { if (simu) { - throw new SonyProjectorException("readInput failed: should not be called in simu mode"); + throw new CommunicationException("readInput failed: should not be called in simu mode"); } InputStream dataIn = this.dataIn; if (dataIn == null) { - throw new SonyProjectorException("readInput failed: input stream is null"); + throw new CommunicationException("readInput failed: input stream is null"); } try { return dataIn.read(dataBuffer); } catch (IOException e) { logger.debug("readInput failed: {}", e.getMessage()); - throw new SonyProjectorException("readInput failed: " + e.getMessage()); + throw new CommunicationException("readInput failed", e); } } @@ -1074,23 +1069,23 @@ protected int readInput(byte[] dataBuffer) throws SonyProjectorException { * * @param message the buffer containing the message to be sent * - * @throws SonyProjectorException - In case of any communication problem + * @throws CommunicationException - In case of any communication problem */ - protected void writeCommand(byte[] message) throws SonyProjectorException { + protected void writeCommand(byte[] message) throws CommunicationException { logger.debug("writeCommand: {}", HexUtils.bytesToHex(message)); if (simu) { return; } OutputStream dataOut = this.dataOut; if (dataOut == null) { - throw new SonyProjectorException("writeCommand failed: output stream is null"); + throw new CommunicationException("writeCommand failed: output stream is null"); } try { dataOut.write(message); dataOut.flush(); } catch (IOException e) { logger.debug("writeCommand failed: {}", e.getMessage()); - throw new SonyProjectorException("writeCommand failed: " + e.getMessage()); + throw new CommunicationException("writeCommand failed", e); } } @@ -1099,9 +1094,9 @@ protected void writeCommand(byte[] message) throws SonyProjectorException { * * @return the buffer containing the returned message * - * @throws SonyProjectorException - In case of any communication problem + * @throws CommunicationException - In case of any communication problem */ - protected abstract byte[] readResponse() throws SonyProjectorException; + protected abstract byte[] readResponse() throws CommunicationException; /** * Validate the content of a returned message @@ -1109,10 +1104,10 @@ protected void writeCommand(byte[] message) throws SonyProjectorException { * @param responseMessage the buffer containing the returned message * @param the projector setting to get or set * - * @throws SonyProjectorException - If the message has unexpected content + * @throws CommunicationException - If the message has unexpected content */ protected abstract void validateResponse(byte[] responseMessage, SonyProjectorItem item) - throws SonyProjectorException; + throws CommunicationException; /** * Extract the value from the returned message diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpConnector.java b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpConnector.java index 21d7a39417791..cbaf6f83f491d 100644 --- a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpConnector.java +++ b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpConnector.java @@ -28,6 +28,8 @@ import org.openhab.binding.sonyprojector.internal.SonyProjectorModel; import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorConnector; import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorItem; +import org.openhab.core.i18n.CommunicationException; +import org.openhab.core.i18n.ConnectionException; import org.openhab.core.util.HexUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -114,7 +116,7 @@ public String getCommunity() { } @Override - public synchronized void open() throws SonyProjectorException { + public synchronized void open() throws ConnectionException { if (!connected) { logger.debug("Opening SDCP connection IP {} port {}", this.address, this.port); try { @@ -130,8 +132,7 @@ public synchronized void open() throws SonyProjectorException { logger.debug("SDCP connection opened"); } catch (IOException | SecurityException | IllegalArgumentException e) { - logger.debug("Opening SDCP connection failed: {}", e.getMessage()); - throw new SonyProjectorException("Opening SDCP connection failed: " + e.getMessage()); + throw new ConnectionException("@text/exception.opening-sdcp-connection-failed", e); } } } @@ -181,15 +182,15 @@ protected byte[] buildMessage(SonyProjectorItem item, boolean getCommand, byte[] * @param dataBuffer the buffer into which the data is read. * @return the total number of bytes read into the buffer, or -1 if there is no more data because the end of the * stream has been reached. - * @throws SonyProjectorException - If the input stream is null, if the first byte cannot be read for any reason + * @throws CommunicationException - If the input stream is null, if the first byte cannot be read for any reason * other than the end of the file, if the input stream has been closed, or if some other I/O error * occurs. */ @Override - protected int readInput(byte[] dataBuffer) throws SonyProjectorException { + protected int readInput(byte[] dataBuffer) throws CommunicationException { InputStream dataIn = this.dataIn; if (dataIn == null) { - throw new SonyProjectorException("readInput failed: input stream is null"); + throw new CommunicationException("readInput failed: input stream is null"); } try { return dataIn.read(dataBuffer); @@ -197,12 +198,12 @@ protected int readInput(byte[] dataBuffer) throws SonyProjectorException { return 0; } catch (IOException e) { logger.debug("readInput failed: {}", e.getMessage()); - throw new SonyProjectorException("readInput failed: " + e.getMessage()); + throw new CommunicationException("readInput failed", e); } } @Override - protected synchronized byte[] readResponse() throws SonyProjectorException { + protected synchronized byte[] readResponse() throws CommunicationException { logger.debug("readResponse (timeout = {} ms)...", READ_TIMEOUT_MS); byte[] message = new byte[MSG_MAX_SIZE]; boolean timeout = false; @@ -222,22 +223,22 @@ protected synchronized byte[] readResponse() throws SonyProjectorException { } if ((count < MSG_MIN_SIZE) && timeout) { logger.debug("readResponse timeout: only {} bytes read after {} ms", count, READ_TIMEOUT_MS); - throw new SonyProjectorException("readResponse failed: timeout"); + throw new CommunicationException("readResponse failed: timeout"); } logger.debug("readResponse: {}", HexUtils.bytesToHex(message)); if (count < MSG_MIN_SIZE) { logger.debug("readResponse: unexpected response data length: {}", count); - throw new SonyProjectorException("Unexpected response data length"); + throw new CommunicationException("Unexpected response data length"); } return message; } @Override - protected void validateResponse(byte[] responseMessage, SonyProjectorItem item) throws SonyProjectorException { + protected void validateResponse(byte[] responseMessage, SonyProjectorItem item) throws CommunicationException { // Check response size if (responseMessage.length < MSG_MIN_SIZE) { logger.debug("Unexpected response data length: {}", responseMessage.length); - throw new SonyProjectorException("Unexpected response data length"); + throw new CommunicationException("Unexpected response data length"); } // Header should be a sony projector header @@ -245,7 +246,7 @@ protected void validateResponse(byte[] responseMessage, SonyProjectorItem item) if (!Arrays.equals(headerMsg, HEADER)) { logger.debug("Unexpected HEADER in response: {} rather than {}", HexUtils.bytesToHex(headerMsg), HexUtils.bytesToHex(HEADER)); - throw new SonyProjectorException("Unexpected HEADER in response"); + throw new CommunicationException("Unexpected HEADER in response"); } // Community should be the same as used for sending @@ -253,7 +254,7 @@ protected void validateResponse(byte[] responseMessage, SonyProjectorItem item) if (!Arrays.equals(communityResponseMsg, community.getBytes())) { logger.debug("Unexpected community in response: {} rather than {}", HexUtils.bytesToHex(communityResponseMsg), HexUtils.bytesToHex(community.getBytes())); - throw new SonyProjectorException("Unexpected community in response"); + throw new CommunicationException("Unexpected community in response"); } // Item number should be the same as used for sending @@ -261,14 +262,14 @@ protected void validateResponse(byte[] responseMessage, SonyProjectorItem item) if (!Arrays.equals(itemResponseMsg, item.getCode())) { logger.debug("Unexpected item number in response: {} rather than {}", HexUtils.bytesToHex(itemResponseMsg), HexUtils.bytesToHex(item.getCode())); - throw new SonyProjectorException("Unexpected item number in response"); + throw new CommunicationException("Unexpected item number in response"); } // Check response size int dataLength = responseMessage[9] & 0x000000FF; if (responseMessage.length < (10 + dataLength)) { logger.debug("Unexpected response data length: {}", dataLength); - throw new SonyProjectorException("Unexpected response data length"); + throw new CommunicationException("Unexpected response data length"); } // byte 7 is expected to be 1, which indicates that the request was successful @@ -279,11 +280,11 @@ protected void validateResponse(byte[] responseMessage, SonyProjectorItem item) try { SonyProjectorSdcpError error = SonyProjectorSdcpError.getFromDataCode(errorCode); msg = error.getMessage(); - } catch (SonyProjectorException e) { + } catch (CommunicationException e) { } } logger.debug("{} received in response", msg); - throw new SonyProjectorException(msg + " received in response"); + throw new CommunicationException(msg + " received in response"); } } diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpError.java b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpError.java index 4520f182d49e1..4a221063eec62 100644 --- a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpError.java +++ b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpError.java @@ -15,7 +15,7 @@ import java.util.Arrays; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.binding.sonyprojector.internal.SonyProjectorException; +import org.openhab.core.i18n.CommunicationException; import org.openhab.core.util.HexUtils; /** @@ -89,14 +89,14 @@ public byte[] getDataCode() { * * @return the error associated to the data code * - * @throws SonyProjectorException - If no error is associated to the data code + * @throws CommunicationException - If no error is associated to the data code */ - public static SonyProjectorSdcpError getFromDataCode(byte[] dataCode) throws SonyProjectorException { + public static SonyProjectorSdcpError getFromDataCode(byte[] dataCode) throws CommunicationException { for (SonyProjectorSdcpError value : SonyProjectorSdcpError.values()) { if (Arrays.equals(dataCode, value.getDataCode())) { return value; } } - throw new SonyProjectorException("Unknwon error code: " + HexUtils.bytesToHex(dataCode)); + throw new CommunicationException("Unknwon error code: " + HexUtils.bytesToHex(dataCode)); } } diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpSimuConnector.java b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpSimuConnector.java index 608882e45dd4f..4aadd64fd69c1 100644 --- a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpSimuConnector.java +++ b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpSimuConnector.java @@ -13,9 +13,10 @@ package org.openhab.binding.sonyprojector.internal.communication.sdcp; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.binding.sonyprojector.internal.SonyProjectorException; import org.openhab.binding.sonyprojector.internal.SonyProjectorModel; import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorItem; +import org.openhab.core.i18n.CommunicationException; +import org.openhab.core.i18n.ConnectionException; import org.openhab.core.util.HexUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,7 +45,7 @@ public SonyProjectorSdcpSimuConnector(SonyProjectorModel model) { } @Override - public synchronized void open() throws SonyProjectorException { + public synchronized void open() throws ConnectionException { if (!connected) { connected = true; logger.debug("Simulated SDCP connection opened"); @@ -66,7 +67,7 @@ protected byte[] buildMessage(SonyProjectorItem item, boolean getCommand, byte[] } @Override - protected synchronized byte[] readResponse() throws SonyProjectorException { + protected synchronized byte[] readResponse() throws CommunicationException { byte[] message = new byte[34]; byte[] communityData = getCommunity().getBytes(); message[0] = HEADER[0]; diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialConnector.java b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialConnector.java index 673c86182d184..f99f799dc80cc 100644 --- a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialConnector.java +++ b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialConnector.java @@ -15,17 +15,17 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.TooManyListenersException; import java.util.concurrent.TimeUnit; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.sonyprojector.internal.SonyProjectorException; import org.openhab.binding.sonyprojector.internal.SonyProjectorModel; import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorConnector; import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorItem; +import org.openhab.core.i18n.CommunicationException; +import org.openhab.core.i18n.ConnectionException; import org.openhab.core.io.transport.serial.PortInUseException; import org.openhab.core.io.transport.serial.SerialPort; import org.openhab.core.io.transport.serial.SerialPortEvent; @@ -91,14 +91,13 @@ public SonyProjectorSerialConnector(SerialPortManager serialPortManager, String } @Override - public synchronized void open() throws SonyProjectorException { + public synchronized void open() throws ConnectionException { if (!connected) { logger.debug("Opening serial connection on port {}", serialPortName); try { SerialPortIdentifier portIdentifier = serialPortManager.getIdentifier(serialPortName); if (portIdentifier == null) { - logger.debug("Opening serial connection failed: No Such Port: {}", serialPortName); - throw new SonyProjectorException("Opening serial connection failed: No Such Port"); + throw new ConnectionException("@text/exception.invalid-serial-port", serialPortName); } SerialPort commPort = portIdentifier.open(this.getClass().getName(), 2000); @@ -139,20 +138,8 @@ public synchronized void open() throws SonyProjectorException { connected = true; logger.debug("Serial connection opened"); - } catch (PortInUseException e) { - logger.debug("Opening serial connection failed: Port in Use Exception: {}", e.getMessage(), e); - throw new SonyProjectorException("Opening serial connection failed: Port in Use Exception"); - } catch (UnsupportedCommOperationException e) { - logger.debug("Opening serial connection failed: Unsupported Comm Operation Exception: {}", - e.getMessage(), e); - throw new SonyProjectorException( - "Opening serial connection failed: Unsupported Comm Operation Exception"); - } catch (UnsupportedEncodingException e) { - logger.debug("Opening serial connection failed: Unsupported Encoding Exception: {}", e.getMessage(), e); - throw new SonyProjectorException("Opening serial connection failed: Unsupported Encoding Exception"); - } catch (IOException e) { - logger.debug("Opening serial connection failed: IO Exception: {}", e.getMessage(), e); - throw new SonyProjectorException("Opening serial connection failed: IO Exception"); + } catch (PortInUseException | UnsupportedCommOperationException | IOException e) { + throw new ConnectionException("@text/exception.opening-serial-connection-failed", e); } } } @@ -189,7 +176,7 @@ protected byte[] buildMessage(SonyProjectorItem item, boolean getCommand, byte[] } @Override - protected synchronized byte[] readResponse() throws SonyProjectorException { + protected synchronized byte[] readResponse() throws CommunicationException { logger.debug("readResponse (timeout = {} ms)...", READ_TIMEOUT_MS); byte[] message = new byte[8]; boolean startCodeReached = false; @@ -221,7 +208,7 @@ protected synchronized byte[] readResponse() throws SonyProjectorException { } if (!endCodeReached && timeout) { logger.debug("readResponse timeout: only {} bytes read after {} ms", index, READ_TIMEOUT_MS); - throw new SonyProjectorException("readResponse failed: timeout"); + throw new CommunicationException("readResponse failed: timeout"); } logger.debug("readResponse: {}", HexUtils.bytesToHex(message)); @@ -229,31 +216,31 @@ protected synchronized byte[] readResponse() throws SonyProjectorException { } @Override - protected void validateResponse(byte[] responseMessage, SonyProjectorItem item) throws SonyProjectorException { + protected void validateResponse(byte[] responseMessage, SonyProjectorItem item) throws CommunicationException { if (responseMessage.length != 8) { logger.debug("Unexpected response data length: {}", responseMessage.length); - throw new SonyProjectorException("Unexpected response data length"); + throw new CommunicationException("Unexpected response data length"); } // Check START CODE if (responseMessage[0] != START_CODE) { logger.debug("Unexpected message START CODE in response: {} rather than {}", Integer.toHexString(responseMessage[0] & 0x000000FF), Integer.toHexString(START_CODE & 0x000000FF)); - throw new SonyProjectorException("Unexpected message START CODE in response"); + throw new CommunicationException("Unexpected message START CODE in response"); } // Check END CODE if (responseMessage[7] != END_CODE) { logger.debug("Unexpected message END CODE in response: {} rather than {}", Integer.toHexString(responseMessage[7] & 0x000000FF), Integer.toHexString(END_CODE & 0x000000FF)); - throw new SonyProjectorException("Unexpected message END CODE in response"); + throw new CommunicationException("Unexpected message END CODE in response"); } byte checksum = computeCheckSum(responseMessage); if (responseMessage[6] != checksum) { logger.debug("Invalid check sum in response: {} rather than {}", Integer.toHexString(responseMessage[6] & 0x000000FF), Integer.toHexString(checksum & 0x000000FF)); - throw new SonyProjectorException("Invalid check sum in response"); + throw new CommunicationException("Invalid check sum in response"); } if (responseMessage[3] == TYPE_ITEM) { @@ -262,7 +249,7 @@ protected void validateResponse(byte[] responseMessage, SonyProjectorItem item) if (!Arrays.equals(itemResponseMsg, item.getCode())) { logger.debug("Unexpected item number in response: {} rather than {}", HexUtils.bytesToHex(itemResponseMsg), HexUtils.bytesToHex(item.getCode())); - throw new SonyProjectorException("Unexpected item number in response"); + throw new CommunicationException("Unexpected item number in response"); } } else if (responseMessage[3] == TYPE_ACK) { // ACK @@ -272,14 +259,14 @@ protected void validateResponse(byte[] responseMessage, SonyProjectorItem item) try { SonyProjectorSerialError error = SonyProjectorSerialError.getFromDataCode(errorCode); msg = error.getMessage(); - } catch (SonyProjectorException e) { + } catch (CommunicationException e) { } logger.debug("{} received in response", msg); - throw new SonyProjectorException(msg + " received in response"); + throw new CommunicationException(msg + " received in response"); } } else { logger.debug("Unexpected TYPE in response: {}", Integer.toHexString(responseMessage[3] & 0x000000FF)); - throw new SonyProjectorException("Unexpected TYPE in response"); + throw new CommunicationException("Unexpected TYPE in response"); } } diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialError.java b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialError.java index 79a5ea4d0fcd9..7ca04b5981eda 100644 --- a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialError.java +++ b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialError.java @@ -15,7 +15,7 @@ import java.util.Arrays; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.binding.sonyprojector.internal.SonyProjectorException; +import org.openhab.core.i18n.CommunicationException; import org.openhab.core.util.HexUtils; /** @@ -77,14 +77,14 @@ public byte[] getDataCode() { * * @return the error associated to the searched data code * - * @throws SonyProjectorException - If no error is associated to the searched data code + * @throws CommunicationException - If no error is associated to the searched data code */ - public static SonyProjectorSerialError getFromDataCode(byte[] dataCode) throws SonyProjectorException { + public static SonyProjectorSerialError getFromDataCode(byte[] dataCode) throws CommunicationException { for (SonyProjectorSerialError value : SonyProjectorSerialError.values()) { if (Arrays.equals(dataCode, value.getDataCode())) { return value; } } - throw new SonyProjectorException("Unknwon error code: " + HexUtils.bytesToHex(dataCode)); + throw new CommunicationException("Unknwon error code: " + HexUtils.bytesToHex(dataCode)); } } diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialOverIpConnector.java b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialOverIpConnector.java index 6487941b0b89b..8428dc4e009ea 100644 --- a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialOverIpConnector.java +++ b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialOverIpConnector.java @@ -21,8 +21,9 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.sonyprojector.internal.SonyProjectorException; import org.openhab.binding.sonyprojector.internal.SonyProjectorModel; +import org.openhab.core.i18n.CommunicationException; +import org.openhab.core.i18n.ConnectionException; import org.openhab.core.io.transport.serial.SerialPortManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,7 +60,7 @@ public SonyProjectorSerialOverIpConnector(SerialPortManager serialPortManager, S } @Override - public synchronized void open() throws SonyProjectorException { + public synchronized void open() throws ConnectionException { if (!connected) { logger.debug("Opening serial over IP connection on IP {} port {}", this.address, this.port); try { @@ -75,8 +76,7 @@ public synchronized void open() throws SonyProjectorException { logger.debug("Serial over IP connection opened"); } catch (IOException | SecurityException | IllegalArgumentException e) { - logger.debug("Opening serial over IP connection failed: {}", e.getMessage()); - throw new SonyProjectorException("Opening serial over IP connection failed: " + e.getMessage()); + throw new ConnectionException("@text/exception.opening-serial-over-ip-connection-failed", e); } } } @@ -106,15 +106,15 @@ public synchronized void close() { * @param dataBuffer the buffer into which the data is read. * @return the total number of bytes read into the buffer, or -1 if there is no more data because the end of the * stream has been reached. - * @throws SonyProjectorException - If the input stream is null, if the first byte cannot be read for any reason + * @throws CommunicationException - If the input stream is null, if the first byte cannot be read for any reason * other than the end of the file, if the input stream has been closed, or if some other I/O error * occurs. */ @Override - protected int readInput(byte[] dataBuffer) throws SonyProjectorException { + protected int readInput(byte[] dataBuffer) throws CommunicationException { InputStream dataIn = this.dataIn; if (dataIn == null) { - throw new SonyProjectorException("readInput failed: input stream is null"); + throw new CommunicationException("readInput failed: input stream is null"); } try { return dataIn.read(dataBuffer); @@ -122,7 +122,7 @@ protected int readInput(byte[] dataBuffer) throws SonyProjectorException { return 0; } catch (IOException e) { logger.debug("readInput failed: {}", e.getMessage()); - throw new SonyProjectorException("readInput failed: " + e.getMessage()); + throw new CommunicationException("readInput failed", e); } } } diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialSimuConnector.java b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialSimuConnector.java index 43cfeaf76c5ef..638c2e0006c30 100644 --- a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialSimuConnector.java +++ b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialSimuConnector.java @@ -13,8 +13,9 @@ package org.openhab.binding.sonyprojector.internal.communication.serial; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.binding.sonyprojector.internal.SonyProjectorException; import org.openhab.binding.sonyprojector.internal.SonyProjectorModel; +import org.openhab.core.i18n.CommunicationException; +import org.openhab.core.i18n.ConnectionException; import org.openhab.core.io.transport.serial.SerialPortManager; import org.openhab.core.util.HexUtils; import org.slf4j.Logger; @@ -41,7 +42,7 @@ public SonyProjectorSerialSimuConnector(SerialPortManager serialPortManager, Son } @Override - public synchronized void open() throws SonyProjectorException { + public synchronized void open() throws ConnectionException { if (!connected) { connected = true; logger.debug("Simulated serial connection opened"); @@ -57,7 +58,7 @@ public synchronized void close() { } @Override - protected synchronized byte[] readResponse() throws SonyProjectorException { + protected synchronized byte[] readResponse() throws CommunicationException { byte[] message = new byte[8]; message[0] = START_CODE; message[1] = SonyProjectorSerialError.COMPLETE.getDataCode()[0]; diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/handler/SonyProjectorHandler.java b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/handler/SonyProjectorHandler.java index d4d5f7996002e..916b16f01a188 100644 --- a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/handler/SonyProjectorHandler.java +++ b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/handler/SonyProjectorHandler.java @@ -33,6 +33,8 @@ import org.openhab.binding.sonyprojector.internal.configuration.SonyProjectorSerialConfiguration; import org.openhab.binding.sonyprojector.internal.configuration.SonyProjectorSerialOverIpConfiguration; import org.openhab.core.cache.ExpiringCacheMap; +import org.openhab.core.i18n.ConnectionException; +import org.openhab.core.i18n.TranslationProvider; import org.openhab.core.io.transport.serial.SerialPortManager; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; @@ -47,6 +49,8 @@ import org.openhab.core.types.RefreshType; import org.openhab.core.types.State; import org.openhab.core.types.UnDefType; +import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,31 +64,36 @@ @NonNullByDefault public class SonyProjectorHandler extends BaseThingHandler { - private final Logger logger = LoggerFactory.getLogger(SonyProjectorHandler.class); - private static final SonyProjectorModel DEFAULT_MODEL = SonyProjectorModel.VW520; private static final long POLLING_INTERVAL = TimeUnit.SECONDS.toSeconds(15); + private final Logger logger = LoggerFactory.getLogger(SonyProjectorHandler.class); + + private final SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider; + private final SerialPortManager serialPortManager; + private final TranslationProvider i18nProvider; + + private final Bundle bundle; + + private final ExpiringCacheMap cache; + private @Nullable ScheduledFuture refreshJob; private boolean identifyProjector; private SonyProjectorModel projectorModel = DEFAULT_MODEL; private SonyProjectorConnector connector = new SonyProjectorSdcpSimuConnector(DEFAULT_MODEL); - private SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider; - private SerialPortManager serialPortManager; - private boolean simu; private final Object commandLock = new Object(); - private final ExpiringCacheMap cache; - public SonyProjectorHandler(Thing thing, SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider, - SerialPortManager serialPortManager) { + SerialPortManager serialPortManager, TranslationProvider i18nProvider) { super(thing); this.stateDescriptionProvider = stateDescriptionProvider; this.serialPortManager = serialPortManager; + this.i18nProvider = i18nProvider; + this.bundle = FrameworkUtil.getBundle(this.getClass()); this.cache = new ExpiringCacheMap<>(TimeUnit.SECONDS.toMillis(POLLING_INTERVAL)); } @@ -102,9 +111,10 @@ public void handleCommand(ChannelUID channelUID, Command command) { synchronized (commandLock) { try { connector.open(); - } catch (SonyProjectorException e) { - logger.debug("Command {} from channel {} failed: {}", command, channel, e.getMessage()); - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage()); + } catch (ConnectionException e) { + logger.debug("Command {} from channel {} failed: {}", command, channel, + e.getMessage(bundle, i18nProvider)); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getRawMessage()); return; } try { @@ -405,9 +415,9 @@ private void pollProjector() { try { connector.open(); - } catch (SonyProjectorException e) { - logger.debug("Poll projector failed: {}", e.getMessage()); - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage()); + } catch (ConnectionException e) { + logger.debug("Poll projector failed: {}", e.getMessage(bundle, i18nProvider), e); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getRawMessage()); return; } diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/i18n/sonyprojector.properties b/bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/i18n/sonyprojector.properties index 1f6e51989db6d..70dad31f4d20e 100644 --- a/bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/i18n/sonyprojector.properties +++ b/bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/i18n/sonyprojector.properties @@ -296,3 +296,10 @@ offline.config-error-unknown-port = Undefined port configuration setting offline.config-error-invalid-port = Invalid port configuration setting offline.config-error-unknown-model = Undefined model configuration setting offline.config-error-invalid-thing-type = Use serial over IP connection thing type + + Exceptions + +exception.invalid-serial-port = Opening serial connection failed: no port {0} +exception.opening-serial-connection-failed = Opening serial connection failed +exception.opening-serial-over-ip-connection-failed = Opening serial over IP connection failed +exception.opening-sdcp-connection-failed = Opening SDCP connection failed diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/i18n/sonyprojector_fr.properties b/bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/i18n/sonyprojector_fr.properties index c41a02a839308..1c1dcf1874fc8 100644 --- a/bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/i18n/sonyprojector_fr.properties +++ b/bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/i18n/sonyprojector_fr.properties @@ -296,3 +296,10 @@ offline.config-error-unknown-port = Paramètre de port indéfini offline.config-error-invalid-port = Paramètre de port invalide offline.config-error-unknown-model = Paramètre de modèle indéfini offline.config-error-invalid-thing-type = Utiliser le type connexion série sur IP + + Exceptions + +exception.invalid-serial-port = Echec de l''ouverture de la connexion série: pas de port {0} +exception.opening-serial-connection-failed = Echec de l''ouverture de la connexion série +exception.opening-serial-over-ip-connection-failed = Echec de l''ouverture de la connexion série sur IP +exception.opening-sdcp-connection-failed = Echec de l''ouverture de la connexion SDCP