Skip to content

Commit b4bcf80

Browse files
authored
[benqprojector] Fix response processing for newer projectors (openhab#18009)
* Fix message processing for newer projectors Signed-off-by: Michael Lobstein <[email protected]>
1 parent b5203eb commit b4bcf80

File tree

6 files changed

+50
-24
lines changed

6 files changed

+50
-24
lines changed

bundles/org.openhab.binding.benqprojector/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ String benqAspectRatio "Aspect Ratio [%s]" { channel="benqprojector:p
8989
Switch benqFreeze { channel="benqprojector:projector-serial:hometheater:freeze" }
9090
Switch benqBlank { channel="benqprojector:projector-serial:hometheater:blank" }
9191
String benqDirect { channel="benqprojector:projector-serial:hometheater:directcmd" }
92-
Number benqLampTime "Lamp Time [%d h]" <switch> { channel="benqprojector:projector-serial:hometheater:lamptime" }
92+
Number benqLampTime "Lamp Time [%d h]" <light> { channel="benqprojector:projector-serial:hometheater:lamptime" }
9393
```
9494

9595
sitemaps/benq.sitemap
@@ -98,7 +98,7 @@ sitemaps/benq.sitemap
9898
sitemap benq label="BenQ Projector" {
9999
Frame label="Controls" {
100100
Switch item=benqPower label="Power"
101-
Selection item=benqSource label="Source" mappings=["hdmi"="HDMI", "hdmi2"="HDMI2", "ypbr"="Component", "RGB"="Computer", "vid"="Video", "svid"="S-Video"]
101+
Selection item=benqSource label="Source" mappings=["hdmi"="HDMI", "hdmi2"="HDMI2", "usbreader"="USB Reader", "ypbr"="Component", "RGB"="Computer", "vid"="Video", "svid"="S-Video"]
102102
Selection item=benqPictureMode label="Picture Mode"
103103
Selection item=benqAspectRatio label="Aspect Ratio"
104104
Switch item=benqFreeze label="Freeze"

bundles/org.openhab.binding.benqprojector/src/main/java/org/openhab/binding/benqprojector/internal/BenqProjectorBindingConstants.java

+3
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,7 @@ public class BenqProjectorBindingConstants {
4242
// Config properties
4343
public static final String THING_PROPERTY_HOST = "host";
4444
public static final String THING_PROPERTY_PORT = "port";
45+
46+
// Unsupported item response
47+
public static final String UNSUPPORTED_ITM = "Unsupported item";
4548
}

bundles/org.openhab.binding.benqprojector/src/main/java/org/openhab/binding/benqprojector/internal/BenqProjectorDevice.java

+13-16
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
*/
1313
package org.openhab.binding.benqprojector.internal;
1414

15+
import static org.openhab.binding.benqprojector.internal.BenqProjectorBindingConstants.*;
16+
1517
import java.time.Duration;
18+
import java.util.Locale;
1619

1720
import org.eclipse.jdt.annotation.NonNullByDefault;
1821
import org.eclipse.jdt.annotation.Nullable;
@@ -33,10 +36,6 @@
3336
*/
3437
@NonNullByDefault
3538
public class BenqProjectorDevice {
36-
private static final String UNSUPPORTED_ITM = "Unsupported item";
37-
private static final String BLOCK_ITM = "Block item";
38-
private static final String ILLEGAL_FMT = "Illegal format";
39-
4039
private static final int LAMP_REFRESH_WAIT_MINUTES = 5;
4140

4241
private ExpiringCache<Integer> cachedLampHours = new ExpiringCache<>(Duration.ofMinutes(LAMP_REFRESH_WAIT_MINUTES),
@@ -67,14 +66,6 @@ private synchronized String sendQuery(String query) throws BenqProjectorCommandE
6766
return "UNSUPPORTED";
6867
}
6968

70-
if (response.contains(BLOCK_ITM)) {
71-
throw new BenqProjectorCommandException("Block Item received for command: " + query);
72-
}
73-
74-
if (response.contains(ILLEGAL_FMT)) {
75-
throw new BenqProjectorCommandException("Illegal Format response received for command: " + query);
76-
}
77-
7869
logger.debug("Response: '{}'", response);
7970

8071
// example: SOUR=HDMI2
@@ -122,11 +113,17 @@ public boolean isConnected() {
122113
* Power
123114
*/
124115
public Switch getPowerStatus() throws BenqProjectorCommandException, BenqProjectorException {
125-
return (queryString("pow=?").contains("on") ? Switch.ON : Switch.OFF);
116+
return (queryString("pow=?").toLowerCase(Locale.ENGLISH).contains("on") ? Switch.ON : Switch.OFF);
126117
}
127118

128119
public void setPower(Switch value) throws BenqProjectorCommandException, BenqProjectorException {
129-
sendCommand(value == Switch.ON ? "pow=on" : "pow=off");
120+
if (value == Switch.ON) {
121+
sendCommand("pow=on");
122+
} else {
123+
// some projectors need the off command twice to switch off
124+
sendCommand("pow=off");
125+
sendCommand("pow=off");
126+
}
130127
}
131128

132129
/*
@@ -166,7 +163,7 @@ public void setAspectRatio(String value) throws BenqProjectorCommandException, B
166163
* Blank Screen
167164
*/
168165
public Switch getBlank() throws BenqProjectorCommandException, BenqProjectorException {
169-
return (queryString("blank=?").contains("on") ? Switch.ON : Switch.OFF);
166+
return (queryString("blank=?").toLowerCase(Locale.ENGLISH).contains("on") ? Switch.ON : Switch.OFF);
170167
}
171168

172169
public void setBlank(Switch value) throws BenqProjectorCommandException, BenqProjectorException {
@@ -177,7 +174,7 @@ public void setBlank(Switch value) throws BenqProjectorCommandException, BenqPro
177174
* Freeze
178175
*/
179176
public Switch getFreeze() throws BenqProjectorCommandException, BenqProjectorException {
180-
return (queryString("freeze=?").contains("on") ? Switch.ON : Switch.OFF);
177+
return (queryString("freeze=?").toLowerCase(Locale.ENGLISH).contains("on") ? Switch.ON : Switch.OFF);
181178
}
182179

183180
public void setFreeze(Switch value) throws BenqProjectorCommandException, BenqProjectorException {

bundles/org.openhab.binding.benqprojector/src/main/java/org/openhab/binding/benqprojector/internal/connector/BenqProjectorConnector.java

+28-4
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
*/
1313
package org.openhab.binding.benqprojector.internal.connector;
1414

15+
import static org.openhab.binding.benqprojector.internal.BenqProjectorBindingConstants.*;
16+
1517
import java.io.IOException;
1618
import java.io.InputStream;
1719
import java.io.OutputStream;
1820
import java.nio.charset.StandardCharsets;
1921

2022
import org.eclipse.jdt.annotation.NonNullByDefault;
2123
import org.eclipse.jdt.annotation.Nullable;
24+
import org.openhab.binding.benqprojector.internal.BenqProjectorCommandException;
2225
import org.openhab.binding.benqprojector.internal.BenqProjectorException;
2326

2427
/**
@@ -34,6 +37,9 @@ public interface BenqProjectorConnector {
3437
static final String END = "#\r";
3538
static final String BLANK = "";
3639

40+
static final String BLOCK_ITM = "Block item";
41+
static final String ILLEGAL_FMT = "Illegal format";
42+
3743
/**
3844
* Procedure for connecting to projector.
3945
*
@@ -55,8 +61,9 @@ public interface BenqProjectorConnector {
5561
* Message to send.
5662
*
5763
* @throws BenqProjectorException
64+
* @throws BenqProjectorCommandException
5865
*/
59-
String sendMessage(String data) throws BenqProjectorException;
66+
String sendMessage(String data) throws BenqProjectorException, BenqProjectorCommandException;
6067

6168
/**
6269
* Common method called by the Serial or Tcp connector to send the message to the projector, wait for a response and
@@ -70,9 +77,10 @@ public interface BenqProjectorConnector {
7077
* The connector's output stream.
7178
*
7279
* @throws BenqProjectorException
80+
* @throws BenqProjectorCommandException
7381
*/
7482
default String sendMsgReadResp(String data, @Nullable InputStream in, @Nullable OutputStream out)
75-
throws IOException, BenqProjectorException {
83+
throws IOException, BenqProjectorException, BenqProjectorCommandException {
7684
String resp = BLANK;
7785

7886
if (in != null && out != null) {
@@ -88,8 +96,24 @@ default String sendMsgReadResp(String data, @Nullable InputStream in, @Nullable
8896
byte[] tmpData = new byte[availableBytes];
8997
int readBytes = in.read(tmpData, 0, availableBytes);
9098
resp = resp.concat(new String(tmpData, 0, readBytes, StandardCharsets.US_ASCII));
91-
if (resp.contains(END)) {
92-
return resp.replaceAll("[\\r\\n*#>]", BLANK).replace(data, BLANK);
99+
100+
if (resp.contains(UNSUPPORTED_ITM)) {
101+
return resp;
102+
}
103+
104+
if (resp.contains(BLOCK_ITM)) {
105+
throw new BenqProjectorCommandException("Block Item received for command: " + data);
106+
}
107+
108+
if (resp.contains(ILLEGAL_FMT)) {
109+
throw new BenqProjectorCommandException(
110+
"Illegal Format response received for command: " + data);
111+
}
112+
113+
// The response is fully received when the second '#' arrives
114+
// example: *pow=?# *POW=ON#
115+
if (resp.chars().filter(ch -> ch == '#').count() >= 2) {
116+
return resp.replaceAll("[\\s\\r\\n*#>]", BLANK).replace(data, BLANK);
93117
}
94118
} else {
95119
try {

bundles/org.openhab.binding.benqprojector/src/main/java/org/openhab/binding/benqprojector/internal/connector/BenqProjectorSerialConnector.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.eclipse.jdt.annotation.NonNullByDefault;
2020
import org.eclipse.jdt.annotation.Nullable;
21+
import org.openhab.binding.benqprojector.internal.BenqProjectorCommandException;
2122
import org.openhab.binding.benqprojector.internal.BenqProjectorException;
2223
import org.openhab.core.io.transport.serial.PortInUseException;
2324
import org.openhab.core.io.transport.serial.SerialPort;
@@ -120,7 +121,7 @@ public void disconnect() throws BenqProjectorException {
120121
}
121122

122123
@Override
123-
public String sendMessage(String data) throws BenqProjectorException {
124+
public String sendMessage(String data) throws BenqProjectorException, BenqProjectorCommandException {
124125
InputStream in = this.in;
125126
OutputStream out = this.out;
126127

bundles/org.openhab.binding.benqprojector/src/main/java/org/openhab/binding/benqprojector/internal/connector/BenqProjectorTcpConnector.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import org.eclipse.jdt.annotation.NonNullByDefault;
2121
import org.eclipse.jdt.annotation.Nullable;
22+
import org.openhab.binding.benqprojector.internal.BenqProjectorCommandException;
2223
import org.openhab.binding.benqprojector.internal.BenqProjectorException;
2324
import org.slf4j.Logger;
2425
import org.slf4j.LoggerFactory;
@@ -99,7 +100,7 @@ public void disconnect() throws BenqProjectorException {
99100
}
100101

101102
@Override
102-
public String sendMessage(String data) throws BenqProjectorException {
103+
public String sendMessage(String data) throws BenqProjectorException, BenqProjectorCommandException {
103104
InputStream in = this.in;
104105
OutputStream out = this.out;
105106

0 commit comments

Comments
 (0)