Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[benqprojector] Fix response processing for newer projectors #18009

Merged
merged 6 commits into from
Jan 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bundles/org.openhab.binding.benqprojector/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ String benqAspectRatio "Aspect Ratio [%s]" { channel="benqprojector:p
Switch benqFreeze { channel="benqprojector:projector-serial:hometheater:freeze" }
Switch benqBlank { channel="benqprojector:projector-serial:hometheater:blank" }
String benqDirect { channel="benqprojector:projector-serial:hometheater:directcmd" }
Number benqLampTime "Lamp Time [%d h]" <switch> { channel="benqprojector:projector-serial:hometheater:lamptime" }
Number benqLampTime "Lamp Time [%d h]" <light> { channel="benqprojector:projector-serial:hometheater:lamptime" }
```

sitemaps/benq.sitemap
Expand All @@ -98,7 +98,7 @@ sitemaps/benq.sitemap
sitemap benq label="BenQ Projector" {
Frame label="Controls" {
Switch item=benqPower label="Power"
Selection item=benqSource label="Source" mappings=["hdmi"="HDMI", "hdmi2"="HDMI2", "ypbr"="Component", "RGB"="Computer", "vid"="Video", "svid"="S-Video"]
Selection item=benqSource label="Source" mappings=["hdmi"="HDMI", "hdmi2"="HDMI2", "usbreader"="USB Reader", "ypbr"="Component", "RGB"="Computer", "vid"="Video", "svid"="S-Video"]
Selection item=benqPictureMode label="Picture Mode"
Selection item=benqAspectRatio label="Aspect Ratio"
Switch item=benqFreeze label="Freeze"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,7 @@ public class BenqProjectorBindingConstants {
// Config properties
public static final String THING_PROPERTY_HOST = "host";
public static final String THING_PROPERTY_PORT = "port";

// Unsupported item response
public static final String UNSUPPORTED_ITM = "Unsupported item";
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
*/
package org.openhab.binding.benqprojector.internal;

import static org.openhab.binding.benqprojector.internal.BenqProjectorBindingConstants.*;

import java.time.Duration;
import java.util.Locale;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
Expand All @@ -33,10 +36,6 @@
*/
@NonNullByDefault
public class BenqProjectorDevice {
private static final String UNSUPPORTED_ITM = "Unsupported item";
private static final String BLOCK_ITM = "Block item";
private static final String ILLEGAL_FMT = "Illegal format";

private static final int LAMP_REFRESH_WAIT_MINUTES = 5;

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

if (response.contains(BLOCK_ITM)) {
throw new BenqProjectorCommandException("Block Item received for command: " + query);
}

if (response.contains(ILLEGAL_FMT)) {
throw new BenqProjectorCommandException("Illegal Format response received for command: " + query);
}

logger.debug("Response: '{}'", response);

// example: SOUR=HDMI2
Expand Down Expand Up @@ -122,11 +113,17 @@ public boolean isConnected() {
* Power
*/
public Switch getPowerStatus() throws BenqProjectorCommandException, BenqProjectorException {
return (queryString("pow=?").contains("on") ? Switch.ON : Switch.OFF);
return (queryString("pow=?").toLowerCase(Locale.ENGLISH).contains("on") ? Switch.ON : Switch.OFF);
}

public void setPower(Switch value) throws BenqProjectorCommandException, BenqProjectorException {
sendCommand(value == Switch.ON ? "pow=on" : "pow=off");
if (value == Switch.ON) {
sendCommand("pow=on");
} else {
// some projectors need the off command twice to switch off
sendCommand("pow=off");
sendCommand("pow=off");
lsiepel marked this conversation as resolved.
Show resolved Hide resolved
}
}

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

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

public void setFreeze(Switch value) throws BenqProjectorCommandException, BenqProjectorException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@
*/
package org.openhab.binding.benqprojector.internal.connector;

import static org.openhab.binding.benqprojector.internal.BenqProjectorBindingConstants.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.benqprojector.internal.BenqProjectorCommandException;
import org.openhab.binding.benqprojector.internal.BenqProjectorException;

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

static final String BLOCK_ITM = "Block item";
static final String ILLEGAL_FMT = "Illegal format";

/**
* Procedure for connecting to projector.
*
Expand All @@ -55,8 +61,9 @@ public interface BenqProjectorConnector {
* Message to send.
*
* @throws BenqProjectorException
* @throws BenqProjectorCommandException
*/
String sendMessage(String data) throws BenqProjectorException;
String sendMessage(String data) throws BenqProjectorException, BenqProjectorCommandException;

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

if (in != null && out != null) {
Expand All @@ -88,8 +96,24 @@ default String sendMsgReadResp(String data, @Nullable InputStream in, @Nullable
byte[] tmpData = new byte[availableBytes];
int readBytes = in.read(tmpData, 0, availableBytes);
resp = resp.concat(new String(tmpData, 0, readBytes, StandardCharsets.US_ASCII));
if (resp.contains(END)) {
return resp.replaceAll("[\\r\\n*#>]", BLANK).replace(data, BLANK);

if (resp.contains(UNSUPPORTED_ITM)) {
return resp;
}

if (resp.contains(BLOCK_ITM)) {
throw new BenqProjectorCommandException("Block Item received for command: " + data);
}

if (resp.contains(ILLEGAL_FMT)) {
throw new BenqProjectorCommandException(
"Illegal Format response received for command: " + data);
}

// The response is fully received when the second '#' arrives
// example: *pow=?# *POW=ON#
if (resp.chars().filter(ch -> ch == '#').count() >= 2) {
return resp.replaceAll("[\\s\\r\\n*#>]", BLANK).replace(data, BLANK);
}
} else {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.benqprojector.internal.BenqProjectorCommandException;
import org.openhab.binding.benqprojector.internal.BenqProjectorException;
import org.openhab.core.io.transport.serial.PortInUseException;
import org.openhab.core.io.transport.serial.SerialPort;
Expand Down Expand Up @@ -120,7 +121,7 @@ public void disconnect() throws BenqProjectorException {
}

@Override
public String sendMessage(String data) throws BenqProjectorException {
public String sendMessage(String data) throws BenqProjectorException, BenqProjectorCommandException {
InputStream in = this.in;
OutputStream out = this.out;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.benqprojector.internal.BenqProjectorCommandException;
import org.openhab.binding.benqprojector.internal.BenqProjectorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -99,7 +100,7 @@ public void disconnect() throws BenqProjectorException {
}

@Override
public String sendMessage(String data) throws BenqProjectorException {
public String sendMessage(String data) throws BenqProjectorException, BenqProjectorCommandException {
InputStream in = this.in;
OutputStream out = this.out;

Expand Down