mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[epsonprojector] Update epsonprojector binding for OH3 (#9021)
* baseline EpsonProjector code from ysc * Improvements for OH3 * Finish epsonprojector binding for OH3 * improve exception logging * cleanup exception logging * Make connection specific thing types Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
This commit is contained in:
parent
48dcb27a61
commit
ffe252ccd5
@ -63,6 +63,7 @@
|
|||||||
/bundles/org.openhab.binding.enigma2/ @gdolfen
|
/bundles/org.openhab.binding.enigma2/ @gdolfen
|
||||||
/bundles/org.openhab.binding.enocean/ @fruggy83
|
/bundles/org.openhab.binding.enocean/ @fruggy83
|
||||||
/bundles/org.openhab.binding.enturno/ @klocsson
|
/bundles/org.openhab.binding.enturno/ @klocsson
|
||||||
|
/bundles/org.openhab.binding.epsonprojector/ @mlobstein
|
||||||
/bundles/org.openhab.binding.etherrain/ @dfad1469
|
/bundles/org.openhab.binding.etherrain/ @dfad1469
|
||||||
/bundles/org.openhab.binding.evohome/ @Nebula83
|
/bundles/org.openhab.binding.evohome/ @Nebula83
|
||||||
/bundles/org.openhab.binding.exec/ @kgoderis
|
/bundles/org.openhab.binding.exec/ @kgoderis
|
||||||
|
@ -306,6 +306,11 @@
|
|||||||
<artifactId>org.openhab.binding.enturno</artifactId>
|
<artifactId>org.openhab.binding.enturno</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openhab.addons.bundles</groupId>
|
||||||
|
<artifactId>org.openhab.binding.epsonprojector</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openhab.addons.bundles</groupId>
|
<groupId>org.openhab.addons.bundles</groupId>
|
||||||
<artifactId>org.openhab.binding.etherrain</artifactId>
|
<artifactId>org.openhab.binding.etherrain</artifactId>
|
||||||
|
13
bundles/org.openhab.binding.epsonprojector/NOTICE
Normal file
13
bundles/org.openhab.binding.epsonprojector/NOTICE
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
This content is produced and maintained by the openHAB project.
|
||||||
|
|
||||||
|
* Project home: https://www.openhab.org
|
||||||
|
|
||||||
|
== Declared Project Licenses
|
||||||
|
|
||||||
|
This program and the accompanying materials are made available under the terms
|
||||||
|
of the Eclipse Public License 2.0 which is available at
|
||||||
|
https://www.eclipse.org/legal/epl-2.0/.
|
||||||
|
|
||||||
|
== Source Code
|
||||||
|
|
||||||
|
https://github.com/openhab/openhab-addons
|
174
bundles/org.openhab.binding.epsonprojector/README.md
Normal file
174
bundles/org.openhab.binding.epsonprojector/README.md
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
# Epson Projector Binding
|
||||||
|
|
||||||
|
This binding is compatible with Epson projectors that support the ESC/VP21 protocol over a serial port or USB to serial adapter.
|
||||||
|
Alternatively, you can connect to your projector via a TCP connection using a serial over IP device or by using`ser2net`.
|
||||||
|
|
||||||
|
## Supported Things
|
||||||
|
|
||||||
|
This binding supports two thing types based on the connection used: `projector-serial` and `projector-tcp`.
|
||||||
|
|
||||||
|
## Discovery
|
||||||
|
|
||||||
|
The projector thing cannot be auto-discovered, it has to be configured manually.
|
||||||
|
|
||||||
|
## Binding Configuration
|
||||||
|
|
||||||
|
There are no overall binding configuration settings that need to be set.
|
||||||
|
All settings are through thing configuration parameters.
|
||||||
|
|
||||||
|
## Thing Configuration
|
||||||
|
|
||||||
|
The `projector-serial` thing has the following configuration parameters:
|
||||||
|
|
||||||
|
- _serialPort_: Serial port device name that is connected to the Epson projector to control, e.g. COM1 on Windows, /dev/ttyS0 on Linux or /dev/tty.PL2303-0000103D on Mac
|
||||||
|
- _pollingInterval_: Polling interval in seconds to update channel states | 5-60 seconds; default 10 seconds
|
||||||
|
|
||||||
|
The `projector-tcp` thing has the following configuration parameters:
|
||||||
|
|
||||||
|
- _host_: IP address for the serial over IP device
|
||||||
|
- _port_: Port for the serial over IP device
|
||||||
|
- _pollingInterval_: Polling interval in seconds to update channel states | 5-60 seconds; default 10 seconds
|
||||||
|
|
||||||
|
Some notes:
|
||||||
|
|
||||||
|
* The binding should work on all Epson projectors that support the ESC/VP21 protocol, however not all binding channels will be useable on all projectors.
|
||||||
|
* The _source_ channel includes a dropdown with the most common source inputs.
|
||||||
|
* If your projector has a source input that is not in the dropdown, the two digit hex code to access that input will be displayed by the _source_ channel when that input is selected by the remote control.
|
||||||
|
* By using the sitemap mapping or a rule to send the input's code back to the _source_ channel, any source on the projector can be accessed by the binding.
|
||||||
|
* The following channels _aspectratio_, _colormode_, _luminance_, _gamma_ and _background_ are pre-populated with a full set of options and not every option will be useable on all projectors.
|
||||||
|
* If your projector has an option in one of the above mentioned channels that is not recognized by the binding, the channel will display 'UNKNOWN' if that un-recognized option is selected by the remote control.
|
||||||
|
* If the projector power is switched to off in the middle of a polling operation, some of the channel values may become undefined until the projector is switched on again.
|
||||||
|
|
||||||
|
* On Linux, you may get an error stating the serial port cannot be opened when the epsonprojector binding tries to load.
|
||||||
|
* You can get around this by adding the `openhab` user to the `dialout` group like this: `usermod -a -G dialout openhab`.
|
||||||
|
* Also on Linux you may have issues with the USB if using two serial USB devices e.g. epsonprojector and RFXcom. See the [general documentation about serial port configuration](/docs/administration/serial.html) for more on symlinking the USB ports.
|
||||||
|
* Here is an example of ser2net.conf you can use to share your serial port /dev/ttyUSB0 on IP port 4444 using [ser2net Linux tool](https://sourceforge.net/projects/ser2net/) (take care, the baud rate is specific to the Epson projector):
|
||||||
|
|
||||||
|
```
|
||||||
|
4444:raw:0:/dev/ttyUSB0:9600 8DATABITS NONE 1STOPBIT LOCAL
|
||||||
|
```
|
||||||
|
|
||||||
|
## Channels
|
||||||
|
|
||||||
|
| Channel | Item Type | Purpose | Values |
|
||||||
|
| ------------------ | --------- | --------------------------------------------------- | --------- |
|
||||||
|
| power | Switch | Powers the projector on or off. | |
|
||||||
|
| powerstate | String | Retrieves the textual power state of the projector. | Read only |
|
||||||
|
| source | String | Retrieve or set the input source. | See above |
|
||||||
|
| aspectratio | String | Retrieve or set the aspect ratio. | See above |
|
||||||
|
| colormode | String | Retrieve or set the color mode. | See above |
|
||||||
|
| freeze | Switch | Turn the freeze screen mode on or off. | |
|
||||||
|
| mute | Switch | Turn the AV mute on or off. | |
|
||||||
|
| volume | Number | Retrieve or set the volume. | 0 - +20 |
|
||||||
|
| luminance | String | Retrieve or set the lamp mode. | See above |
|
||||||
|
| brightness | Number | Retrieve or set the brightness. | -24 - +24 |
|
||||||
|
| contrast | Number | Retrieve or set the contrast. | -24 - +24 |
|
||||||
|
| density | Number | Retrieve or set the density (color saturation). | -32 - +32 |
|
||||||
|
| tint | Number | Retrieve or set the tint. | -32 - +32 |
|
||||||
|
| colortemperature | Number | Retrieve or set the color temperature. | 0 - +9 |
|
||||||
|
| fleshtemperature | Number | Retrieve or set the flesh temperature. | 0 - +6 |
|
||||||
|
| gamma | String | Retrieve or set the gamma setting. | See above |
|
||||||
|
| autokeystone | Switch | Turn the auto keystone mode on or off. | |
|
||||||
|
| verticalkeystone | Number | Retrieve or set the vertical keystone. | -30 - +30 |
|
||||||
|
| horizontalkeystone | Number | Retrieve or set the horizontal keystone. | -30 - +30 |
|
||||||
|
| verticalposition | Number | Retrieve or set the vertical position. | -8 - +10 |
|
||||||
|
| horizontalposition | Number | Retrieve or set the horizontal position. | -23 - +26 |
|
||||||
|
| verticalreverse | Switch | Turn the vertical reverse mode on or off. | |
|
||||||
|
| horizontalreverse | Switch | Turn the horizontal reverse mode on or off. | |
|
||||||
|
| background | String | Retrieve or set the background color/logo. | See above |
|
||||||
|
| keycode | Number | Send a key operation command to the projector. | Send only |
|
||||||
|
| lamptime | Number | Retrieves the lamp hours. | Read only |
|
||||||
|
| errcode | Number | Retrieves the last error code. | Read only |
|
||||||
|
| errmessage | String | Retrieves the description of the last error. | Read only |
|
||||||
|
|
||||||
|
## Full Example
|
||||||
|
|
||||||
|
things/epson.things:
|
||||||
|
|
||||||
|
```java
|
||||||
|
//serial port connection
|
||||||
|
epsonprojector:projector-serial:hometheater "Projector" [ serialPort="COM5", pollingInterval=10 ]
|
||||||
|
|
||||||
|
// serial over IP connection
|
||||||
|
epsonprojector:projector-tcp:hometheater "Projector" [ host="192.168.0.10", port=4444, pollingInterval=10 ]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
items/epson.items
|
||||||
|
|
||||||
|
```
|
||||||
|
Switch epsonPower { channel="epsonprojector:projector:hometheater:power" }
|
||||||
|
String epsonSource "Source [%s]" { channel="epsonprojector:projector:hometheater:source" }
|
||||||
|
String epsonAspectRatio "Aspect Ratio [%s]" { channel="epsonprojector:projector:hometheater:aspectratio" }
|
||||||
|
String epsonColorMode "Color Mode [%s]" { channel="epsonprojector:projector:hometheater:colormode" }
|
||||||
|
Switch epsonFreeze { channel="epsonprojector:projector:hometheater:freeze" }
|
||||||
|
Switch epsonMute { channel="epsonprojector:projector:hometheater:mute" }
|
||||||
|
Number epsonVolume { channel="epsonprojector:projector:hometheater:volume" }
|
||||||
|
String epsonLuminance "Lamp Mode [%s]" { channel="epsonprojector:projector:hometheater:luminance" }
|
||||||
|
|
||||||
|
Number epsonBrightness { channel="epsonprojector:projector:hometheater:brightness" }
|
||||||
|
Number epsonContrast { channel="epsonprojector:projector:hometheater:contrast" }
|
||||||
|
Number epsonDensity { channel="epsonprojector:projector:hometheater:density" }
|
||||||
|
Number epsonTint { channel="epsonprojector:projector:hometheater:tint" }
|
||||||
|
Number epsonColorTemperature { channel="epsonprojector:projector:hometheater:colortemperature" }
|
||||||
|
Number epsonFleshTemperature { channel="epsonprojector:projector:hometheater:fleshtemperature" }
|
||||||
|
String epsonGamma "Gamma [%s]" { channel="epsonprojector:projector:hometheater:gamma" }
|
||||||
|
|
||||||
|
Switch epsonAutokeystone { channel="epsonprojector:projector:hometheater:autokeystone" }
|
||||||
|
Number epsonVerticalKeystone { channel="epsonprojector:projector:hometheater:verticalkeystone" }
|
||||||
|
Number epsonHorizontalKeystone { channel="epsonprojector:projector:hometheater:horizontalkeystone" }
|
||||||
|
Number epsonVerticalPosition { channel="epsonprojector:projector:hometheater:verticalposition" }
|
||||||
|
Number epsonHorizontalPosition { channel="epsonprojector:projector:hometheater:horizontalposition" }
|
||||||
|
Switch epsonVerticalReverse { channel="epsonprojector:projector:hometheater:verticalreverse" }
|
||||||
|
Switch epsonHorizontalReverse { channel="epsonprojector:projector:hometheater:horizontalreverse" }
|
||||||
|
|
||||||
|
String epsonBackground "Background [%s]" { channel="epsonprojector:projector:hometheater:background" }
|
||||||
|
String epsonPowerState "Power State [%s]" <switch> { channel="epsonprojector:projector:hometheater:powerstate" }
|
||||||
|
Number epsonLampTime "Lamp Time [%d h]" <switch> { channel="epsonprojector:projector:hometheater:lamptime" }
|
||||||
|
Number epsonErrCode "Error Code [%d]" <"siren-on"> { channel="epsonprojector:projector:hometheater:errcode" }
|
||||||
|
String epsonErrMessage "Error Message [%s]" <"siren-off"> { channel="epsonprojector:projector:hometheater:errmessage" }
|
||||||
|
```
|
||||||
|
|
||||||
|
sitemaps/epson.sitemap
|
||||||
|
|
||||||
|
```
|
||||||
|
sitemap epson label="Epson Projector Demo"
|
||||||
|
{
|
||||||
|
Frame label="Controls" {
|
||||||
|
Switch item=epsonPower label="Power"
|
||||||
|
Selection item=epsonSource label="Source" mappings=["30"="HDMI1", "A0"="HDMI2", "14"="Component", "20"="PC DSUB", "41"="Video", "42"="S-Video"]
|
||||||
|
Switch item=epsonFreeze label="Freeze"
|
||||||
|
Switch item=epsonMute label="AV Mute"
|
||||||
|
Setpoint item=epsonVolume label="Volume"
|
||||||
|
|
||||||
|
}
|
||||||
|
Frame label="Adjust Image" {
|
||||||
|
Setpoint item=epsonBrightness label="Brightness"
|
||||||
|
Setpoint item=epsonContrast label="Contrast"
|
||||||
|
Setpoint item=epsonDensity label="Color Saturation"
|
||||||
|
Setpoint item=epsonTint label="Tint"
|
||||||
|
Switch item=epsonAutokeystone label="Auto Keystone"
|
||||||
|
Setpoint item=epsonVerticalKeystone label="Vertical Keystone"
|
||||||
|
Setpoint item=epsonHorizontalKeystone label="Horizontal Keystone"
|
||||||
|
Setpoint item=epsonVerticalPosition label="Vertical Position"
|
||||||
|
Setpoint item=epsonHorizontalPosition label="Horizontal Position"
|
||||||
|
Selection item=epsonBackground label="Background"
|
||||||
|
}
|
||||||
|
Frame label="Flip Projection" {
|
||||||
|
Switch item=epsonVerticalReverse label="Vertical Reverse"
|
||||||
|
Switch item=epsonHorizontalReverse label="Horizontal Reverse"
|
||||||
|
}
|
||||||
|
Frame label="Info" {
|
||||||
|
Text item=epsonAspectRatio
|
||||||
|
Text item=epsonColorMode
|
||||||
|
Text item=epsonColorTemperature label="Color Temperature"
|
||||||
|
Text item=epsonFleshTemperature label="Flesh Temperature"
|
||||||
|
Text item=epsonGamma
|
||||||
|
Text item=epsonLuminance
|
||||||
|
Text item=epsonPowerState
|
||||||
|
Text item=epsonLampTime
|
||||||
|
Text item=epsonErrCode
|
||||||
|
Text item=epsonErrMessage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
17
bundles/org.openhab.binding.epsonprojector/pom.xml
Normal file
17
bundles/org.openhab.binding.epsonprojector/pom.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.openhab.addons.bundles</groupId>
|
||||||
|
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||||
|
<version>3.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>org.openhab.binding.epsonprojector</artifactId>
|
||||||
|
|
||||||
|
<name>openHAB Add-ons :: Bundles :: Epson Projector Binding</name>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<features name="org.openhab.binding.epsonprojector-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||||
|
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||||
|
|
||||||
|
<feature name="openhab-binding-epsonprojector" description="Epson Projector Binding" version="${project.version}">
|
||||||
|
<feature>openhab-runtime-base</feature>
|
||||||
|
<feature>openhab-transport-serial</feature>
|
||||||
|
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.epsonprojector/${project.version}</bundle>
|
||||||
|
</feature>
|
||||||
|
</features>
|
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link EpsonProjectorBindingConstants} class defines common constants, which are
|
||||||
|
* used across the whole binding.
|
||||||
|
*
|
||||||
|
* @author Yannick Schaus - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class EpsonProjectorBindingConstants {
|
||||||
|
|
||||||
|
private static final String BINDING_ID = "epsonprojector";
|
||||||
|
|
||||||
|
// List of all Thing Type UIDs
|
||||||
|
public static final ThingTypeUID THING_TYPE_PROJECTOR_SERIAL = new ThingTypeUID(BINDING_ID, "projector-serial");
|
||||||
|
public static final ThingTypeUID THING_TYPE_PROJECTOR_TCP = new ThingTypeUID(BINDING_ID, "projector-tcp");
|
||||||
|
|
||||||
|
// Some Channel types
|
||||||
|
public static final String CHANNEL_TYPE_POWER = "power";
|
||||||
|
public static final String CHANNEL_TYPE_POWERSTATE = "powerstate";
|
||||||
|
public static final String CHANNEL_TYPE_LAMPTIME = "lamptime";
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception for Epson projector command errors.
|
||||||
|
*
|
||||||
|
* @author Michael Lobstein - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class EpsonProjectorCommandException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -8048415193494625295L;
|
||||||
|
|
||||||
|
public EpsonProjectorCommandException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal;
|
||||||
|
|
||||||
|
import java.io.InvalidClassException;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.core.items.Item;
|
||||||
|
import org.openhab.core.library.items.NumberItem;
|
||||||
|
import org.openhab.core.library.items.StringItem;
|
||||||
|
import org.openhab.core.library.items.SwitchItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents all valid command types which could be processed by this
|
||||||
|
* binding.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public enum EpsonProjectorCommandType {
|
||||||
|
POWER("Power", SwitchItem.class),
|
||||||
|
POWER_STATE("PowerState", StringItem.class),
|
||||||
|
LAMP_TIME("LampTime", NumberItem.class),
|
||||||
|
KEY_CODE("KeyCode", NumberItem.class),
|
||||||
|
VKEYSTONE("VerticalKeystone", NumberItem.class),
|
||||||
|
HKEYSTONE("HorizontalKeystone", NumberItem.class),
|
||||||
|
AKEYSTONE("AutoKeystone", SwitchItem.class),
|
||||||
|
FREEZE("Freeze", SwitchItem.class),
|
||||||
|
ASPECT_RATIO("AspectRatio", StringItem.class),
|
||||||
|
LUMINANCE("Luminance", StringItem.class),
|
||||||
|
SOURCE("Source", StringItem.class),
|
||||||
|
BRIGHTNESS("Brightness", NumberItem.class),
|
||||||
|
CONTRAST("Contrast", NumberItem.class),
|
||||||
|
DENSITY("Density", NumberItem.class),
|
||||||
|
TINT("Tint", NumberItem.class),
|
||||||
|
COLOR_TEMP("ColorTemperature", NumberItem.class),
|
||||||
|
FLESH_TEMP("FleshTemperature", NumberItem.class),
|
||||||
|
COLOR_MODE("ColorMode", StringItem.class),
|
||||||
|
HPOSITION("HorizontalPosition", NumberItem.class),
|
||||||
|
VPOSITION("VerticalPosition", NumberItem.class),
|
||||||
|
GAMMA("Gamma", StringItem.class),
|
||||||
|
VOLUME("Volume", NumberItem.class),
|
||||||
|
MUTE("Mute", SwitchItem.class),
|
||||||
|
HREVERSE("HorizontalReverse", SwitchItem.class),
|
||||||
|
VREVERSE("VerticalReverse", SwitchItem.class),
|
||||||
|
BACKGROUND("Background", StringItem.class),
|
||||||
|
ERR_CODE("ErrCode", NumberItem.class),
|
||||||
|
ERR_MESSAGE("ErrMessage", StringItem.class),;
|
||||||
|
|
||||||
|
private final String text;
|
||||||
|
private Class<? extends Item> itemClass;
|
||||||
|
|
||||||
|
private EpsonProjectorCommandType(final String text, Class<? extends Item> itemClass) {
|
||||||
|
this.text = text;
|
||||||
|
this.itemClass = itemClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<? extends Item> getItemClass() {
|
||||||
|
return itemClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Procedure to validate command type string.
|
||||||
|
*
|
||||||
|
* @param commandTypeText
|
||||||
|
* command string e.g. RawData, Command, Brightness
|
||||||
|
* @return true if item is valid.
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* Not valid command type.
|
||||||
|
* @throws InvalidClassException
|
||||||
|
* Not valid class for command type.
|
||||||
|
*/
|
||||||
|
public static boolean validateBinding(String commandTypeText, Class<? extends Item> itemClass)
|
||||||
|
throws IllegalArgumentException, InvalidClassException {
|
||||||
|
for (EpsonProjectorCommandType c : EpsonProjectorCommandType.values()) {
|
||||||
|
if (c.text.equalsIgnoreCase(commandTypeText)) {
|
||||||
|
if (c.getItemClass().equals(itemClass)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new InvalidClassException("Not valid class for command type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Not valid command type");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Procedure to convert command type string to command type class.
|
||||||
|
*
|
||||||
|
* @param commandTypeText
|
||||||
|
* command string e.g. RawData, Command, Brightness
|
||||||
|
* @return corresponding command type.
|
||||||
|
* @throws InvalidClassException
|
||||||
|
* Not valid class for command type.
|
||||||
|
*/
|
||||||
|
public static EpsonProjectorCommandType getCommandType(String commandTypeText) throws IllegalArgumentException {
|
||||||
|
for (EpsonProjectorCommandType c : EpsonProjectorCommandType.values()) {
|
||||||
|
if (c.text.equalsIgnoreCase(commandTypeText)) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Not valid command type");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,626 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.configuration.EpsonProjectorConfiguration;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.connector.EpsonProjectorConnector;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.connector.EpsonProjectorSerialConnector;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.connector.EpsonProjectorTcpConnector;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.AspectRatio;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.Background;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.ColorMode;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.ErrorMessage;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.Gamma;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.Luminance;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.PowerStatus;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.Switch;
|
||||||
|
import org.openhab.core.cache.ExpiringCache;
|
||||||
|
import org.openhab.core.io.transport.serial.SerialPortManager;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide high level interface to Epson projector.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
* @author Yannick Schaus - Refactoring
|
||||||
|
* @author Michael Lobstein - Improvements for OH3
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class EpsonProjectorDevice {
|
||||||
|
private static final int[] MAP64 = new int[] { 0, 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63, 66,
|
||||||
|
70, 74, 78, 82, 86, 90, 94, 98, 102, 106, 110, 114, 118, 122, 126, 129, 133, 137, 141, 145, 149, 153, 157,
|
||||||
|
161, 165, 169, 173, 177, 181, 185, 189, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240,
|
||||||
|
244, 248, 252 };
|
||||||
|
|
||||||
|
private static final int[] MAP60 = new int[] { 0, 4, 8, 12, 16, 20, 25, 29, 33, 37, 41, 46, 50, 54, 58, 62, 67, 71,
|
||||||
|
75, 79, 83, 88, 92, 96, 100, 104, 109, 113, 117, 121, 125, 130, 134, 138, 142, 146, 151, 155, 159, 163, 167,
|
||||||
|
172, 176, 180, 184, 188, 193, 197, 201, 205, 209, 214, 218, 222, 226, 230, 235, 239, 243, 247, 251 };
|
||||||
|
|
||||||
|
private static final int[] MAP49 = new int[] { 0, 5, 10, 15, 20, 25, 30, 35, 40, 46, 51, 56, 61, 66, 71, 76, 81, 87,
|
||||||
|
92, 97, 102, 107, 112, 117, 122, 128, 133, 138, 143, 148, 153, 158, 163, 168, 174, 179, 184, 189, 194, 199,
|
||||||
|
204, 209, 215, 220, 225, 230, 235, 240, 245, 250 };
|
||||||
|
|
||||||
|
private static final int[] MAP48 = new int[] { 0, 5, 10, 15, 20, 26, 31, 36, 41, 47, 52, 57, 62, 67, 73, 78, 83, 88,
|
||||||
|
94, 99, 104, 109, 114, 120, 125, 130, 135, 141, 146, 151, 156, 161, 167, 172, 177, 182, 188, 193, 198, 203,
|
||||||
|
208, 214, 219, 224, 229, 235, 240, 245, 250 };
|
||||||
|
|
||||||
|
private static final int[] MAP20 = new int[] { 0, 12, 24, 36, 48, 60, 73, 85, 97, 109, 121, 134, 146, 158, 170, 182,
|
||||||
|
195, 207, 219, 231, 243 };
|
||||||
|
|
||||||
|
private static final int[] MAP18 = new int[] { 0, 13, 26, 40, 53, 67, 80, 94, 107, 121, 134, 148, 161, 175, 188,
|
||||||
|
202, 215, 229, 242 };
|
||||||
|
|
||||||
|
private static final int[] MAP_COLOR_TEMP = new int[] { 0, 25, 51, 76, 102, 128, 153, 179, 204, 230 };
|
||||||
|
private static final int[] MAP_FLESH_COLOR = new int[] { 0, 36, 73, 109, 146, 182, 219 };
|
||||||
|
|
||||||
|
private static final int DEFAULT_TIMEOUT = 5 * 1000;
|
||||||
|
private static final int POWER_ON_TIMEOUT = 100 * 1000;
|
||||||
|
private static final int POWER_OFF_TIMEOUT = 130 * 1000;
|
||||||
|
private static final int LAMP_REFRESH_WAIT_MINUTES = 5;
|
||||||
|
|
||||||
|
private static final String ON = "ON";
|
||||||
|
private static final String ERR = "ERR";
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(EpsonProjectorDevice.class);
|
||||||
|
|
||||||
|
private @Nullable ScheduledExecutorService scheduler = null;
|
||||||
|
private @Nullable ScheduledFuture<?> timeoutJob;
|
||||||
|
|
||||||
|
private EpsonProjectorConnector connection;
|
||||||
|
private ExpiringCache<Integer> cachedLampHours = new ExpiringCache<>(Duration.ofMinutes(LAMP_REFRESH_WAIT_MINUTES),
|
||||||
|
this::queryLamp);
|
||||||
|
private boolean connected = false;
|
||||||
|
private boolean ready = true;
|
||||||
|
|
||||||
|
public EpsonProjectorDevice(SerialPortManager serialPortManager, EpsonProjectorConfiguration config) {
|
||||||
|
connection = new EpsonProjectorSerialConnector(serialPortManager, config.serialPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EpsonProjectorDevice(EpsonProjectorConfiguration config) {
|
||||||
|
connection = new EpsonProjectorTcpConnector(config.host, config.port);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReady() {
|
||||||
|
return ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScheduler(ScheduledExecutorService scheduler) {
|
||||||
|
this.scheduler = scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized @Nullable String sendQuery(String query, int timeout)
|
||||||
|
throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
logger.debug("Query: '{}'", query);
|
||||||
|
String response = connection.sendMessage(query, timeout);
|
||||||
|
|
||||||
|
if (response.length() == 0) {
|
||||||
|
throw new EpsonProjectorException("No response received");
|
||||||
|
}
|
||||||
|
|
||||||
|
response = response.replace("\r:", "");
|
||||||
|
logger.debug("Response: '{}'", response);
|
||||||
|
|
||||||
|
if (ERR.equals(response)) {
|
||||||
|
throw new EpsonProjectorCommandException("Error response received for command: " + query);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("PWR OFF".equals(query) && ":".equals(response)) {
|
||||||
|
// When PWR OFF command is sent, next command can be sent 10 seconds after the colon is received
|
||||||
|
logger.debug("Refusing further commands for 10 seconds to power OFF completion");
|
||||||
|
ready = false;
|
||||||
|
ScheduledExecutorService scheduler = this.scheduler;
|
||||||
|
if (scheduler != null) {
|
||||||
|
timeoutJob = scheduler.schedule(() -> {
|
||||||
|
ready = true;
|
||||||
|
}, 10, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String splitResponse(@Nullable String response) throws EpsonProjectorException {
|
||||||
|
if (response != null && !"".equals(response)) {
|
||||||
|
String[] pieces = response.split("=");
|
||||||
|
|
||||||
|
if (pieces.length < 2) {
|
||||||
|
throw new EpsonProjectorException("Invalid response from projector: " + response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pieces[1].trim();
|
||||||
|
} else {
|
||||||
|
throw new EpsonProjectorException("No response received");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void sendCommand(String command, int timeout)
|
||||||
|
throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendQuery(command, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void sendCommand(String command) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(command, DEFAULT_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int queryInt(String query, int timeout, int radix)
|
||||||
|
throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
String response = sendQuery(query, timeout);
|
||||||
|
|
||||||
|
String str = splitResponse(response);
|
||||||
|
|
||||||
|
// if the response has two number groups, get the first one (Aspect Ratio does this)
|
||||||
|
if (str.contains(" ")) {
|
||||||
|
String[] subStr = str.split(" ");
|
||||||
|
str = subStr[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Integer.parseInt(str, radix);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int queryInt(String query, int timeout) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
return queryInt(query, timeout, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int queryInt(String query) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
return queryInt(query, DEFAULT_TIMEOUT, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int queryHexInt(String query, int timeout)
|
||||||
|
throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
return queryInt(query, timeout, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int queryHexInt(String query) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
return queryInt(query, DEFAULT_TIMEOUT, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String queryString(String query) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
String response = sendQuery(query, DEFAULT_TIMEOUT);
|
||||||
|
return splitResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connect() throws EpsonProjectorException {
|
||||||
|
connection.connect();
|
||||||
|
connected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect() throws EpsonProjectorException {
|
||||||
|
connection.disconnect();
|
||||||
|
connected = false;
|
||||||
|
ScheduledFuture<?> timeoutJob = this.timeoutJob;
|
||||||
|
if (timeoutJob != null) {
|
||||||
|
timeoutJob.cancel(true);
|
||||||
|
this.timeoutJob = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConnected() {
|
||||||
|
return connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Power
|
||||||
|
*/
|
||||||
|
public PowerStatus getPowerStatus() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int val = queryInt("PWR?");
|
||||||
|
return PowerStatus.forValue(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPower(Switch value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(String.format("PWR %s", value.name()), value == Switch.ON ? POWER_ON_TIMEOUT : POWER_OFF_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Key code
|
||||||
|
*/
|
||||||
|
public void sendKeyCode(int value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(String.format("KEY %02X", value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Vertical Keystone
|
||||||
|
*/
|
||||||
|
public int getVerticalKeystone() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int vkey = queryInt("VKEYSTONE?");
|
||||||
|
for (int i = 0; i < MAP60.length; i++) {
|
||||||
|
if (vkey == MAP60[i]) {
|
||||||
|
return i - 30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVerticalKeystone(int value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
value = value + 30;
|
||||||
|
if (value >= 0 && value <= 60) {
|
||||||
|
sendCommand(String.format("VKEYSTONE %d", MAP60[value]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Horizontal Keystone
|
||||||
|
*/
|
||||||
|
public int getHorizontalKeystone() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int hkey = queryInt("HKEYSTONE?");
|
||||||
|
for (int i = 0; i < MAP60.length; i++) {
|
||||||
|
if (hkey == MAP60[i]) {
|
||||||
|
return i - 30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHorizontalKeystone(int value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
value = value + 30;
|
||||||
|
if (value >= 0 && value <= 60) {
|
||||||
|
sendCommand(String.format("HKEYSTONE %d", MAP60[value]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Auto Keystone
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Switch getAutoKeystone() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
String val = queryString("AUTOKEYSTONE?");
|
||||||
|
return val.equals(ON) ? Switch.ON : Switch.OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoKeystone(Switch value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(String.format("AUTOKEYSTONE %s", value.name()), DEFAULT_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Freeze
|
||||||
|
*/
|
||||||
|
public Switch getFreeze() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
String val = queryString("FREEZE?");
|
||||||
|
return val.equals(ON) ? Switch.ON : Switch.OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFreeze(Switch value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(String.format("FREEZE %s", value.name()), DEFAULT_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Aspect Ratio
|
||||||
|
*/
|
||||||
|
public AspectRatio getAspectRatio() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int val = queryHexInt("ASPECT?");
|
||||||
|
return AspectRatio.forValue(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAspectRatio(AspectRatio value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(String.format("ASPECT %02X", value.toInt()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Luminance
|
||||||
|
*/
|
||||||
|
public Luminance getLuminance() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int val = queryHexInt("LUMINANCE?");
|
||||||
|
return Luminance.forValue(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLuminance(Luminance value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(String.format("LUMINANCE %02X", value.toInt()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Source
|
||||||
|
*/
|
||||||
|
public String getSource() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
return queryString("SOURCE?");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSource(String value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(String.format("SOURCE %s", value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Brightness
|
||||||
|
*/
|
||||||
|
public int getBrightness() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int brt = queryInt("BRIGHT?");
|
||||||
|
for (int i = 0; i < MAP48.length; i++) {
|
||||||
|
if (brt == MAP48[i]) {
|
||||||
|
return i - 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrightness(int value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
value = value + 24;
|
||||||
|
if (value >= 0 && value <= 48) {
|
||||||
|
sendCommand(String.format("BRIGHT %d", MAP48[value]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contrast
|
||||||
|
*/
|
||||||
|
public int getContrast() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int con = queryInt("CONTRAST?");
|
||||||
|
for (int i = 0; i < MAP48.length; i++) {
|
||||||
|
if (con == MAP48[i]) {
|
||||||
|
return i - 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContrast(int value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
value = value + 24;
|
||||||
|
if (value >= 0 && value <= 48) {
|
||||||
|
sendCommand(String.format("CONTRAST %d", MAP48[value]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Density
|
||||||
|
*/
|
||||||
|
public int getDensity() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int den = queryInt("DENSITY?");
|
||||||
|
for (int i = 0; i < MAP64.length; i++) {
|
||||||
|
if (den == MAP64[i]) {
|
||||||
|
return i - 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDensity(int value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
value = value + 32;
|
||||||
|
if (value >= 0 && value <= 64) {
|
||||||
|
sendCommand(String.format("DENSITY %d", MAP64[value]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tint
|
||||||
|
*/
|
||||||
|
public int getTint() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int tint = queryInt("TINT?");
|
||||||
|
for (int i = 0; i < MAP64.length; i++) {
|
||||||
|
if (tint == MAP64[i]) {
|
||||||
|
return i - 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTint(int value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
value = value + 32;
|
||||||
|
if (value >= 0 && value <= 64) {
|
||||||
|
sendCommand(String.format("TINT %d", MAP64[value]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Color Temperature
|
||||||
|
*/
|
||||||
|
public int getColorTemperature() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int ctemp = queryInt("CTEMP?");
|
||||||
|
for (int i = 0; i < MAP_COLOR_TEMP.length; i++) {
|
||||||
|
if (ctemp == MAP_COLOR_TEMP[i]) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColorTemperature(int value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
if (value >= 0 && value <= 9) {
|
||||||
|
sendCommand(String.format("CTEMP %d", MAP_COLOR_TEMP[value]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flesh Color
|
||||||
|
*/
|
||||||
|
public int getFleshColor() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int fclr = queryInt("FCOLOR?");
|
||||||
|
for (int i = 0; i < MAP_FLESH_COLOR.length; i++) {
|
||||||
|
if (fclr == MAP_FLESH_COLOR[i]) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFleshColor(int value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
if (value >= 0 && value <= 6) {
|
||||||
|
sendCommand(String.format("FCOLOR %d", MAP_FLESH_COLOR[value]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Color Mode
|
||||||
|
*/
|
||||||
|
public ColorMode getColorMode() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int val = queryHexInt("CMODE?");
|
||||||
|
return ColorMode.forValue(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColorMode(ColorMode value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(String.format("CMODE %02X", value.toInt()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Horizontal Position
|
||||||
|
*/
|
||||||
|
public int getHorizontalPosition() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int hpos = queryInt("HPOS?");
|
||||||
|
for (int i = 0; i < MAP49.length; i++) {
|
||||||
|
if (hpos == MAP49[i]) {
|
||||||
|
return i - 23;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHorizontalPosition(int value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
value = value + 23;
|
||||||
|
if (value >= 0 && value <= 49) {
|
||||||
|
sendCommand(String.format("HPOS %d", MAP49[value]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Vertical Position
|
||||||
|
*/
|
||||||
|
public int getVerticalPosition() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int vpos = queryInt("VPOS?");
|
||||||
|
for (int i = 0; i < MAP18.length; i++) {
|
||||||
|
if (vpos == MAP18[i]) {
|
||||||
|
return i - 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVerticalPosition(int value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
value = value + 8;
|
||||||
|
if (value >= 0 && value <= 18) {
|
||||||
|
sendCommand(String.format("VPOS %d", MAP18[value]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gamma
|
||||||
|
*/
|
||||||
|
public Gamma getGamma() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int val = queryHexInt("GAMMA?");
|
||||||
|
return Gamma.forValue(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGamma(Gamma value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(String.format("GAMMA %02X", value.toInt()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Volume
|
||||||
|
*/
|
||||||
|
public int getVolume() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int vol = queryInt("VOL?");
|
||||||
|
for (int i = 0; i < MAP20.length; i++) {
|
||||||
|
if (vol == MAP20[i]) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVolume(int value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
if (value >= 0 && value <= 20) {
|
||||||
|
sendCommand(String.format("VOL %d", MAP20[value]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AV Mute
|
||||||
|
*/
|
||||||
|
public Switch getMute() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
String val = queryString("MUTE?");
|
||||||
|
return val.equals(ON) ? Switch.ON : Switch.OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMute(Switch value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(String.format("MUTE %s", value.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Horizontal Reverse
|
||||||
|
*/
|
||||||
|
public Switch getHorizontalReverse() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
String val = queryString("HREVERSE?");
|
||||||
|
return val.equals(ON) ? Switch.ON : Switch.OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHorizontalReverse(Switch value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(String.format("HREVERSE %s", value.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Vertical Reverse
|
||||||
|
*/
|
||||||
|
public Switch getVerticalReverse() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
String val = queryString("VREVERSE?");
|
||||||
|
return val.equals(ON) ? Switch.ON : Switch.OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVerticalReverse(Switch value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(String.format("VREVERSE %s", value.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Background Select for AV Mute
|
||||||
|
*/
|
||||||
|
public Background getBackground() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int val = queryHexInt("MSEL?");
|
||||||
|
return Background.forValue(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackground(Background value) throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
sendCommand(String.format("MSEL %02X", value.toInt()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lamp Time (hours) - get from cache
|
||||||
|
*/
|
||||||
|
public int getLampTime() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
Integer lampHours = cachedLampHours.getValue();
|
||||||
|
|
||||||
|
if (lampHours != null) {
|
||||||
|
return lampHours.intValue();
|
||||||
|
} else {
|
||||||
|
throw new EpsonProjectorCommandException("cachedLampHours returned null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get Lamp Time
|
||||||
|
*/
|
||||||
|
private @Nullable Integer queryLamp() {
|
||||||
|
try {
|
||||||
|
return Integer.valueOf(queryInt("LAMP?"));
|
||||||
|
} catch (EpsonProjectorCommandException | EpsonProjectorException e) {
|
||||||
|
logger.debug("Error executing command LAMP?", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error Code
|
||||||
|
*/
|
||||||
|
public int getError() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
return queryHexInt("ERR?");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error Code Description
|
||||||
|
*/
|
||||||
|
public String getErrorString() throws EpsonProjectorCommandException, EpsonProjectorException {
|
||||||
|
int err = queryInt("ERR?");
|
||||||
|
return ErrorMessage.forCode(err);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception for Epson projector errors.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class EpsonProjectorException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -8048415193494625295L;
|
||||||
|
|
||||||
|
public EpsonProjectorException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EpsonProjectorException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal;
|
||||||
|
|
||||||
|
import static org.openhab.binding.epsonprojector.internal.EpsonProjectorBindingConstants.*;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.handler.EpsonProjectorHandler;
|
||||||
|
import org.openhab.core.io.transport.serial.SerialPortManager;
|
||||||
|
import org.openhab.core.thing.Thing;
|
||||||
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||||
|
import org.openhab.core.thing.binding.ThingHandler;
|
||||||
|
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||||
|
import org.osgi.service.component.annotations.Activate;
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
import org.osgi.service.component.annotations.Reference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link EpsonProjectorHandlerFactory} is responsible for creating things and thing
|
||||||
|
* handlers.
|
||||||
|
*
|
||||||
|
* @author Yannick Schaus - Initial contribution
|
||||||
|
* @author Michael Lobstein - Improvements for OH3
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
@Component(configurationPid = "binding.epsonprojector", service = ThingHandlerFactory.class)
|
||||||
|
public class EpsonProjectorHandlerFactory extends BaseThingHandlerFactory {
|
||||||
|
|
||||||
|
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(
|
||||||
|
Stream.of(THING_TYPE_PROJECTOR_SERIAL, THING_TYPE_PROJECTOR_TCP).collect(Collectors.toSet()));
|
||||||
|
private final SerialPortManager serialPortManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||||
|
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Activate
|
||||||
|
public EpsonProjectorHandlerFactory(final @Reference SerialPortManager serialPortManager) {
|
||||||
|
this.serialPortManager = serialPortManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||||
|
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||||
|
|
||||||
|
if (THING_TYPE_PROJECTOR_SERIAL.equals(thingTypeUID) || THING_TYPE_PROJECTOR_TCP.equals(thingTypeUID)) {
|
||||||
|
return new EpsonProjectorHandler(thing, serialPortManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal.configuration;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link EpsonProjectorConfiguration} class contains fields mapping thing configuration parameters.
|
||||||
|
*
|
||||||
|
* @author Yannick Schaus - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class EpsonProjectorConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serial port used for communication.
|
||||||
|
*/
|
||||||
|
public String serialPort = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Host or IP address used for communication over a TCP link (if serialPort is not set).
|
||||||
|
*/
|
||||||
|
public String host = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Port used for communication over a TCP link (if serialPort is not set).
|
||||||
|
*/
|
||||||
|
public int port;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Polling interval to refresh states.
|
||||||
|
*/
|
||||||
|
public int pollingInterval;
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal.connector;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.EpsonProjectorException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for Epson projector communication.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public interface EpsonProjectorConnector {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Procedure for connecting to projector.
|
||||||
|
*
|
||||||
|
* @throws EpsonProjectorException
|
||||||
|
*/
|
||||||
|
void connect() throws EpsonProjectorException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Procedure for disconnecting to projector controller.
|
||||||
|
*
|
||||||
|
* @throws EpsonProjectorException
|
||||||
|
*/
|
||||||
|
void disconnect() throws EpsonProjectorException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Procedure for send raw data to projector.
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* Message to send.
|
||||||
|
*
|
||||||
|
* @param timeout
|
||||||
|
* timeout to wait response in milliseconds.
|
||||||
|
*
|
||||||
|
* @throws EpsonProjectorException
|
||||||
|
*/
|
||||||
|
String sendMessage(String data, int timeout) throws EpsonProjectorException;
|
||||||
|
}
|
@ -0,0 +1,209 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal.connector;
|
||||||
|
|
||||||
|
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.epsonprojector.internal.EpsonProjectorException;
|
||||||
|
import org.openhab.core.io.transport.serial.PortInUseException;
|
||||||
|
import org.openhab.core.io.transport.serial.SerialPort;
|
||||||
|
import org.openhab.core.io.transport.serial.SerialPortEvent;
|
||||||
|
import org.openhab.core.io.transport.serial.SerialPortEventListener;
|
||||||
|
import org.openhab.core.io.transport.serial.SerialPortIdentifier;
|
||||||
|
import org.openhab.core.io.transport.serial.SerialPortManager;
|
||||||
|
import org.openhab.core.io.transport.serial.UnsupportedCommOperationException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connector for serial port communication.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
* @author Michael Lobstein - Improvements for OH3
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class EpsonProjectorSerialConnector implements EpsonProjectorConnector, SerialPortEventListener {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(EpsonProjectorSerialConnector.class);
|
||||||
|
private final String serialPortName;
|
||||||
|
private final SerialPortManager serialPortManager;
|
||||||
|
|
||||||
|
private @Nullable InputStream in = null;
|
||||||
|
private @Nullable OutputStream out = null;
|
||||||
|
private @Nullable SerialPort serialPort = null;
|
||||||
|
|
||||||
|
public EpsonProjectorSerialConnector(SerialPortManager serialPortManager, String serialPort) {
|
||||||
|
this.serialPortManager = serialPortManager;
|
||||||
|
this.serialPortName = serialPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connect() throws EpsonProjectorException {
|
||||||
|
try {
|
||||||
|
logger.debug("Open connection to serial port '{}'", serialPortName);
|
||||||
|
|
||||||
|
SerialPortIdentifier serialPortIdentifier = serialPortManager.getIdentifier(serialPortName);
|
||||||
|
|
||||||
|
if (serialPortIdentifier == null) {
|
||||||
|
throw new IOException("Unknown serial port");
|
||||||
|
}
|
||||||
|
SerialPort serialPort = serialPortIdentifier.open(this.getClass().getName(), 2000);
|
||||||
|
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
|
||||||
|
serialPort.enableReceiveThreshold(1);
|
||||||
|
serialPort.disableReceiveTimeout();
|
||||||
|
|
||||||
|
InputStream in = serialPort.getInputStream();
|
||||||
|
OutputStream out = serialPort.getOutputStream();
|
||||||
|
|
||||||
|
if (in != null && out != null) {
|
||||||
|
out.flush();
|
||||||
|
if (in.markSupported()) {
|
||||||
|
in.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
serialPort.notifyOnDataAvailable(true);
|
||||||
|
|
||||||
|
this.serialPort = serialPort;
|
||||||
|
this.in = in;
|
||||||
|
this.out = out;
|
||||||
|
}
|
||||||
|
} catch (PortInUseException | UnsupportedCommOperationException | IOException e) {
|
||||||
|
throw new EpsonProjectorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disconnect() throws EpsonProjectorException {
|
||||||
|
InputStream in = this.in;
|
||||||
|
OutputStream out = this.out;
|
||||||
|
SerialPort serialPort = this.serialPort;
|
||||||
|
|
||||||
|
if (out != null) {
|
||||||
|
logger.debug("Close serial out stream");
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.debug("Error occurred when closing serial out stream: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
this.out = null;
|
||||||
|
}
|
||||||
|
if (in != null) {
|
||||||
|
logger.debug("Close serial in stream");
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.debug("Error occurred when closing serial in stream: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
this.in = null;
|
||||||
|
}
|
||||||
|
if (serialPort != null) {
|
||||||
|
logger.debug("Close serial port");
|
||||||
|
serialPort.close();
|
||||||
|
serialPort.removeEventListener();
|
||||||
|
this.serialPort = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("Closed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sendMessage(String data, int timeout) throws EpsonProjectorException {
|
||||||
|
InputStream in = this.in;
|
||||||
|
OutputStream out = this.out;
|
||||||
|
|
||||||
|
if (in == null || out == null) {
|
||||||
|
connect();
|
||||||
|
in = this.in;
|
||||||
|
out = this.out;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (in != null && out != null) {
|
||||||
|
// flush input stream
|
||||||
|
if (in.markSupported()) {
|
||||||
|
in.reset();
|
||||||
|
} else {
|
||||||
|
while (in.available() > 0) {
|
||||||
|
int availableBytes = in.available();
|
||||||
|
|
||||||
|
if (availableBytes > 0) {
|
||||||
|
byte[] tmpData = new byte[availableBytes];
|
||||||
|
in.read(tmpData, 0, availableBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sendMmsg(data, timeout);
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.debug("IO error occurred...reconnect and resend once: {}", e.getMessage());
|
||||||
|
disconnect();
|
||||||
|
connect();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return sendMmsg(data, timeout);
|
||||||
|
} catch (IOException e1) {
|
||||||
|
throw new EpsonProjectorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialEvent(SerialPortEvent arg0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private String sendMmsg(String data, int timeout) throws IOException, EpsonProjectorException {
|
||||||
|
String resp = "";
|
||||||
|
|
||||||
|
InputStream in = this.in;
|
||||||
|
OutputStream out = this.out;
|
||||||
|
|
||||||
|
if (in != null && out != null) {
|
||||||
|
out.write(data.getBytes(StandardCharsets.US_ASCII));
|
||||||
|
out.write("\r\n".getBytes(StandardCharsets.US_ASCII));
|
||||||
|
out.flush();
|
||||||
|
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
long elapsedTime = 0;
|
||||||
|
|
||||||
|
while (elapsedTime < timeout) {
|
||||||
|
int availableBytes = in.available();
|
||||||
|
if (availableBytes > 0) {
|
||||||
|
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(":")) {
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new EpsonProjectorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
elapsedTime = System.currentTimeMillis() - startTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,183 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal.connector;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.EpsonProjectorException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connector for TCP communication.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
* @author Michael Lobstein - Improvements for OH3
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class EpsonProjectorTcpConnector implements EpsonProjectorConnector {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(EpsonProjectorTcpConnector.class);
|
||||||
|
private final String ip;
|
||||||
|
private final int port;
|
||||||
|
|
||||||
|
private @Nullable Socket socket = null;
|
||||||
|
private @Nullable InputStream in = null;
|
||||||
|
private @Nullable OutputStream out = null;
|
||||||
|
|
||||||
|
public EpsonProjectorTcpConnector(String ip, int port) {
|
||||||
|
this.ip = ip;
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connect() throws EpsonProjectorException {
|
||||||
|
logger.debug("Open connection to address'{}:{}'", ip, port);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Socket socket = new Socket(ip, port);
|
||||||
|
this.socket = socket;
|
||||||
|
in = socket.getInputStream();
|
||||||
|
out = socket.getOutputStream();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new EpsonProjectorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disconnect() throws EpsonProjectorException {
|
||||||
|
OutputStream out = this.out;
|
||||||
|
|
||||||
|
if (out != null) {
|
||||||
|
logger.debug("Close tcp out stream");
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.debug("Error occurred when closing tcp out stream: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream in = this.in;
|
||||||
|
if (in != null) {
|
||||||
|
logger.debug("Close tcp in stream");
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.debug("Error occurred when closing tcp in stream: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket socket = this.socket;
|
||||||
|
if (socket != null) {
|
||||||
|
logger.debug("Closing socket");
|
||||||
|
try {
|
||||||
|
socket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.debug("Error occurred when closing tcp socket: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.socket = null;
|
||||||
|
this.out = null;
|
||||||
|
this.in = null;
|
||||||
|
|
||||||
|
logger.debug("Closed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sendMessage(String data, int timeout) throws EpsonProjectorException {
|
||||||
|
InputStream in = this.in;
|
||||||
|
OutputStream out = this.out;
|
||||||
|
|
||||||
|
if (in == null || out == null) {
|
||||||
|
connect();
|
||||||
|
in = this.in;
|
||||||
|
out = this.out;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (in != null) {
|
||||||
|
// flush input stream
|
||||||
|
if (in.markSupported()) {
|
||||||
|
in.reset();
|
||||||
|
} else {
|
||||||
|
while (in.available() > 0) {
|
||||||
|
int availableBytes = in.available();
|
||||||
|
|
||||||
|
if (availableBytes > 0) {
|
||||||
|
byte[] tmpData = new byte[availableBytes];
|
||||||
|
in.read(tmpData, 0, availableBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sendMmsg(data, timeout);
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.debug("IO error occurred...reconnect and resend once: {}", e.getMessage());
|
||||||
|
disconnect();
|
||||||
|
connect();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return sendMmsg(data, timeout);
|
||||||
|
} catch (IOException e1) {
|
||||||
|
throw new EpsonProjectorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String sendMmsg(String data, int timeout) throws IOException, EpsonProjectorException {
|
||||||
|
String resp = "";
|
||||||
|
|
||||||
|
InputStream in = this.in;
|
||||||
|
OutputStream out = this.out;
|
||||||
|
|
||||||
|
if (in != null && out != null) {
|
||||||
|
out.write(data.getBytes(StandardCharsets.US_ASCII));
|
||||||
|
out.write("\r\n".getBytes(StandardCharsets.US_ASCII));
|
||||||
|
out.flush();
|
||||||
|
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
long elapsedTime = 0;
|
||||||
|
|
||||||
|
while (elapsedTime < timeout) {
|
||||||
|
int availableBytes = in.available();
|
||||||
|
if (availableBytes > 0) {
|
||||||
|
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(":")) {
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new EpsonProjectorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
elapsedTime = System.currentTimeMillis() - startTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid values for AspectRatio.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
* @author Yannick Schaus - Refactoring
|
||||||
|
* @author Michael Lobstein - Improvements for OH3
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public enum AspectRatio {
|
||||||
|
NORMAL(0x00),
|
||||||
|
RATIO4X3(0x10),
|
||||||
|
ZOOM4X3(0x12),
|
||||||
|
RATIO16X9(0x20),
|
||||||
|
UP16X9(0x21),
|
||||||
|
DOWN16X9(0x22),
|
||||||
|
AUTO(0x30),
|
||||||
|
FULL(0x40),
|
||||||
|
ZOOM(0x50),
|
||||||
|
REAL(0x60),
|
||||||
|
WIDE(0x70),
|
||||||
|
ANAMORPHIC(0x80),
|
||||||
|
SQUEEZE(0x90),
|
||||||
|
UNKNOWN(0xFF);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
AspectRatio(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AspectRatio forValue(int value) {
|
||||||
|
try {
|
||||||
|
return Arrays.stream(values()).filter(e -> e.value == value).findFirst().get();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int toInt() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid values for Background.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
* @author Yannick Schaus - Refactoring
|
||||||
|
* @author Michael Lobstein - Improvements for OH3
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public enum Background {
|
||||||
|
BLACK(0x00),
|
||||||
|
BLUE(0x01),
|
||||||
|
LOGO(0x02),
|
||||||
|
UNKNOWN(0xFF);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
Background(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Background forValue(int value) {
|
||||||
|
try {
|
||||||
|
return Arrays.stream(values()).filter(e -> e.value == value).findFirst().get();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int toInt() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid values for ColorMode.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
* @author Yannick Schaus - Refactoring
|
||||||
|
* @author Michael Lobstein - Improvements for OH3
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public enum ColorMode {
|
||||||
|
SRGB(0x01),
|
||||||
|
NORMAL(0x02),
|
||||||
|
MEETING(0x03),
|
||||||
|
PRESENTATION(0x04),
|
||||||
|
CINEMANIGHT(0x05),
|
||||||
|
DYNAMIC(0x06),
|
||||||
|
NATURAL(0x07),
|
||||||
|
SPORTS(0x08),
|
||||||
|
HD(0x09),
|
||||||
|
CUSTOM(0x10),
|
||||||
|
BLACKBOARD(0x11),
|
||||||
|
WHITEBOARD(0x12),
|
||||||
|
THX(0x13),
|
||||||
|
PHOTO(0x14),
|
||||||
|
CINEMA(0x15),
|
||||||
|
UNKNOWN16(0x16),
|
||||||
|
CINEMA3D(0x17),
|
||||||
|
DYNAMIC3D(0x18),
|
||||||
|
THX3D(0x19),
|
||||||
|
BWCINEMA(0x20),
|
||||||
|
UNKNOWN21(0x21),
|
||||||
|
DIGITALCINEMA(0x22),
|
||||||
|
SILVER(0x0A),
|
||||||
|
XVCOLOR(0x0B),
|
||||||
|
LIVINGROOM(0x0C),
|
||||||
|
DICOMSIM(0x0F),
|
||||||
|
UNKNOWN(0xFF);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
ColorMode(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ColorMode forValue(int value) {
|
||||||
|
try {
|
||||||
|
return Arrays.stream(values()).filter(e -> e.value == value).findFirst().get();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int toInt() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Messages for documented error codes.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
* @author Yannick Schaus - Refactoring
|
||||||
|
* @author Michael Lobstein - Improvements for OH3
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public enum ErrorMessage {
|
||||||
|
NO_ERROR(0, "No error"),
|
||||||
|
ERROR1(1, "Fan error"),
|
||||||
|
ERROR3(3, "Lamp failure at power on"),
|
||||||
|
ERROR4(4, "High internal temperature error"),
|
||||||
|
ERROR6(6, "Lamp error"),
|
||||||
|
ERROR7(7, "Open Lamp cover door error"),
|
||||||
|
ERROR8(8, "Cinema filter error"),
|
||||||
|
ERROR9(9, "Electric dual-layered capacitor is disconnected"),
|
||||||
|
ERROR10(10, "Auto iris error"),
|
||||||
|
ERROR11(11, "Subsystem error"),
|
||||||
|
ERROR12(12, "Low air flow error"),
|
||||||
|
ERROR13(13, "Air filter air flow sensor error"),
|
||||||
|
ERROR14(14, "Power supply unit error (ballast)"),
|
||||||
|
ERROR15(15, "Shutter error"),
|
||||||
|
ERROR16(16, "Cooling system error (peltier element)"),
|
||||||
|
ERROR17(17, "Cooling system error (pump)"),
|
||||||
|
ERROR18(18, "Static iris error"),
|
||||||
|
ERROR19(19, "Power supply unit error (disagreement of ballast)"),
|
||||||
|
ERROR20(20, "Exhaust shutter error"),
|
||||||
|
ERROR21(21, "Obstacle detection error"),
|
||||||
|
ERROR22(22, "IF board discernment error");
|
||||||
|
|
||||||
|
private final int code;
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
ErrorMessage(int code, String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String forCode(int code) {
|
||||||
|
try {
|
||||||
|
return Arrays.stream(values()).filter(e -> e.code == code).findFirst().get().getMessage();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
return "Unknown error code: " + code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid values for Gamma.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
* @author Yannick Schaus - Refactoring
|
||||||
|
* @author Michael Lobstein - Improvements for OH3
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public enum Gamma {
|
||||||
|
G2_0(0x20),
|
||||||
|
G2_1(0x21),
|
||||||
|
G2_2(0x22),
|
||||||
|
G2_3(0x23),
|
||||||
|
G2_4(0x24),
|
||||||
|
CUSTOM(0xF0),
|
||||||
|
UNKNOWN(0xFF);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
Gamma(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Gamma forValue(int value) {
|
||||||
|
try {
|
||||||
|
return Arrays.stream(values()).filter(e -> e.value == value).findFirst().get();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int toInt() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid values for Luminance.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
* @author Yannick Schaus - Refactoring
|
||||||
|
* @author Michael Lobstein - Improvements for OH3
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public enum Luminance {
|
||||||
|
NORMAL(0x00),
|
||||||
|
ECO(0x01),
|
||||||
|
MEDIUM(0x02),
|
||||||
|
UNKNOWN(0xFF);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
Luminance(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Luminance forValue(int value) {
|
||||||
|
try {
|
||||||
|
return Arrays.stream(values()).filter(e -> e.value == value).findFirst().get();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int toInt() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid values for PowerStatus.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
* @author Yannick Schaus - Refactoring
|
||||||
|
* @author Michael Lobstein - Improvements for OH3
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public enum PowerStatus {
|
||||||
|
STANDBY(0x00),
|
||||||
|
ON(0x01),
|
||||||
|
WARMUP(0x02),
|
||||||
|
COOLDOWN(0x03),
|
||||||
|
STANDBYNETWORKON(0x04),
|
||||||
|
ABNORMALSTANDBY(0x05),
|
||||||
|
UNKNOWN(0xFF);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
PowerStatus(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PowerStatus forValue(int value) {
|
||||||
|
try {
|
||||||
|
return Arrays.stream(values()).filter(e -> e.value == value).findFirst().get();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int toInt() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal.enums;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid values for Epson switch commands.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila - Initial contribution
|
||||||
|
* @author Yannick Schaus - Refactoring
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public enum Switch {
|
||||||
|
ON,
|
||||||
|
OFF;
|
||||||
|
}
|
@ -0,0 +1,417 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.epsonprojector.internal.handler;
|
||||||
|
|
||||||
|
import static org.openhab.binding.epsonprojector.internal.EpsonProjectorBindingConstants.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.EpsonProjectorCommandException;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.EpsonProjectorCommandType;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.EpsonProjectorDevice;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.EpsonProjectorException;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.configuration.EpsonProjectorConfiguration;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.AspectRatio;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.Background;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.ColorMode;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.Gamma;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.Luminance;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.PowerStatus;
|
||||||
|
import org.openhab.binding.epsonprojector.internal.enums.Switch;
|
||||||
|
import org.openhab.core.io.transport.serial.SerialPortManager;
|
||||||
|
import org.openhab.core.library.types.DecimalType;
|
||||||
|
import org.openhab.core.library.types.OnOffType;
|
||||||
|
import org.openhab.core.library.types.StringType;
|
||||||
|
import org.openhab.core.thing.Channel;
|
||||||
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
import org.openhab.core.thing.Thing;
|
||||||
|
import org.openhab.core.thing.ThingStatus;
|
||||||
|
import org.openhab.core.thing.ThingStatusDetail;
|
||||||
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.RefreshType;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
import org.openhab.core.types.UnDefType;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link EpsonProjectorHandler} is responsible for handling commands, which are
|
||||||
|
* sent to one of the channels.
|
||||||
|
*
|
||||||
|
* @author Pauli Anttila, Yannick Schaus - Initial contribution
|
||||||
|
* @author Michael Lobstein - Improvements for OH3
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class EpsonProjectorHandler extends BaseThingHandler {
|
||||||
|
private static final int DEFAULT_POLLING_INTERVAL_SEC = 10;
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(EpsonProjectorHandler.class);
|
||||||
|
private final SerialPortManager serialPortManager;
|
||||||
|
|
||||||
|
private @Nullable ScheduledFuture<?> pollingJob;
|
||||||
|
private Optional<EpsonProjectorDevice> device = Optional.empty();
|
||||||
|
|
||||||
|
private boolean isPowerOn = false;
|
||||||
|
private int pollingInterval = DEFAULT_POLLING_INTERVAL_SEC;
|
||||||
|
|
||||||
|
public EpsonProjectorHandler(Thing thing, SerialPortManager serialPortManager) {
|
||||||
|
super(thing);
|
||||||
|
this.serialPortManager = serialPortManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||||
|
String channelId = channelUID.getId();
|
||||||
|
if (command instanceof RefreshType) {
|
||||||
|
Channel channel = this.thing.getChannel(channelUID);
|
||||||
|
if (channel != null) {
|
||||||
|
updateChannelState(channel);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
EpsonProjectorCommandType epsonCommand = EpsonProjectorCommandType.getCommandType(channelId);
|
||||||
|
sendDataToDevice(epsonCommand, command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
EpsonProjectorConfiguration config = getConfigAs(EpsonProjectorConfiguration.class);
|
||||||
|
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||||
|
|
||||||
|
if (THING_TYPE_PROJECTOR_SERIAL.equals(thingTypeUID)) {
|
||||||
|
device = Optional.of(new EpsonProjectorDevice(serialPortManager, config));
|
||||||
|
} else if (THING_TYPE_PROJECTOR_TCP.equals(thingTypeUID)) {
|
||||||
|
device = Optional.of(new EpsonProjectorDevice(config));
|
||||||
|
} else {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
pollingInterval = config.pollingInterval;
|
||||||
|
device.ifPresent(dev -> dev.setScheduler(scheduler));
|
||||||
|
updateStatus(ThingStatus.UNKNOWN);
|
||||||
|
schedulePollingJob();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule the polling job
|
||||||
|
*/
|
||||||
|
private void schedulePollingJob() {
|
||||||
|
cancelPollingJob();
|
||||||
|
|
||||||
|
pollingJob = scheduler.scheduleWithFixedDelay(() -> {
|
||||||
|
List<Channel> channels = this.thing.getChannels();
|
||||||
|
for (Channel channel : channels) {
|
||||||
|
// only query power & lamp time when projector is off
|
||||||
|
if (isPowerOn || (channel.getUID().getId().equals(CHANNEL_TYPE_POWER)
|
||||||
|
|| channel.getUID().getId().equals(CHANNEL_TYPE_LAMPTIME))) {
|
||||||
|
updateChannelState(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 0, (pollingInterval > 0) ? pollingInterval : DEFAULT_POLLING_INTERVAL_SEC, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel the polling job
|
||||||
|
*/
|
||||||
|
private void cancelPollingJob() {
|
||||||
|
ScheduledFuture<?> pollingJob = this.pollingJob;
|
||||||
|
if (pollingJob != null) {
|
||||||
|
pollingJob.cancel(true);
|
||||||
|
this.pollingJob = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
cancelPollingJob();
|
||||||
|
closeConnection();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateChannelState(Channel channel) {
|
||||||
|
try {
|
||||||
|
if (!isLinked(channel.getUID()) && !channel.getUID().getId().equals(CHANNEL_TYPE_POWER)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EpsonProjectorCommandType epsonCommand = EpsonProjectorCommandType.getCommandType(channel.getUID().getId());
|
||||||
|
|
||||||
|
State state = queryDataFromDevice(epsonCommand);
|
||||||
|
|
||||||
|
if (state != null) {
|
||||||
|
updateStatus(ThingStatus.ONLINE);
|
||||||
|
if (isLinked(channel.getUID())) {
|
||||||
|
updateState(channel.getUID(), state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
logger.warn("Unknown channel {}", channel.getUID().getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private State queryDataFromDevice(EpsonProjectorCommandType commandType) {
|
||||||
|
EpsonProjectorDevice remoteController = device.get();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!remoteController.isConnected()) {
|
||||||
|
remoteController.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!remoteController.isReady()) {
|
||||||
|
logger.debug("Refusing command {} while not ready", commandType.toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (commandType) {
|
||||||
|
case AKEYSTONE:
|
||||||
|
Switch autoKeystone = remoteController.getAutoKeystone();
|
||||||
|
return autoKeystone == Switch.ON ? OnOffType.ON : OnOffType.OFF;
|
||||||
|
case ASPECT_RATIO:
|
||||||
|
AspectRatio aspectRatio = remoteController.getAspectRatio();
|
||||||
|
return new StringType(aspectRatio.toString());
|
||||||
|
case BACKGROUND:
|
||||||
|
Background background = remoteController.getBackground();
|
||||||
|
return new StringType(background.toString());
|
||||||
|
case BRIGHTNESS:
|
||||||
|
int brightness = remoteController.getBrightness();
|
||||||
|
return new DecimalType(brightness);
|
||||||
|
case COLOR_MODE:
|
||||||
|
ColorMode colorMode = remoteController.getColorMode();
|
||||||
|
return new StringType(colorMode.toString());
|
||||||
|
case COLOR_TEMP:
|
||||||
|
int ctemp = remoteController.getColorTemperature();
|
||||||
|
return new DecimalType(ctemp);
|
||||||
|
case CONTRAST:
|
||||||
|
int contrast = remoteController.getContrast();
|
||||||
|
return new DecimalType(contrast);
|
||||||
|
case DENSITY:
|
||||||
|
int density = remoteController.getDensity();
|
||||||
|
return new DecimalType(density);
|
||||||
|
case ERR_CODE:
|
||||||
|
int err = remoteController.getError();
|
||||||
|
return new DecimalType(err);
|
||||||
|
case ERR_MESSAGE:
|
||||||
|
String errString = remoteController.getErrorString();
|
||||||
|
return new StringType(errString);
|
||||||
|
case FLESH_TEMP:
|
||||||
|
int fleshColor = remoteController.getFleshColor();
|
||||||
|
return new DecimalType(fleshColor);
|
||||||
|
case FREEZE:
|
||||||
|
Switch freeze = remoteController.getFreeze();
|
||||||
|
return freeze == Switch.ON ? OnOffType.ON : OnOffType.OFF;
|
||||||
|
case GAMMA:
|
||||||
|
Gamma gamma = remoteController.getGamma();
|
||||||
|
return new StringType(gamma.toString());
|
||||||
|
case HKEYSTONE:
|
||||||
|
int hKeystone = remoteController.getHorizontalKeystone();
|
||||||
|
return new DecimalType(hKeystone);
|
||||||
|
case HPOSITION:
|
||||||
|
int hPosition = remoteController.getHorizontalPosition();
|
||||||
|
return new DecimalType(hPosition);
|
||||||
|
case HREVERSE:
|
||||||
|
Switch hReverse = remoteController.getHorizontalReverse();
|
||||||
|
return hReverse == Switch.ON ? OnOffType.ON : OnOffType.OFF;
|
||||||
|
case KEY_CODE:
|
||||||
|
break;
|
||||||
|
case LAMP_TIME:
|
||||||
|
int lampTime = remoteController.getLampTime();
|
||||||
|
return new DecimalType(lampTime);
|
||||||
|
case LUMINANCE:
|
||||||
|
Luminance luminance = remoteController.getLuminance();
|
||||||
|
return new StringType(luminance.toString());
|
||||||
|
case MUTE:
|
||||||
|
Switch mute = remoteController.getMute();
|
||||||
|
return mute == Switch.ON ? OnOffType.ON : OnOffType.OFF;
|
||||||
|
case POWER:
|
||||||
|
PowerStatus powerStatus = remoteController.getPowerStatus();
|
||||||
|
if (isLinked(CHANNEL_TYPE_POWERSTATE)) {
|
||||||
|
updateState(CHANNEL_TYPE_POWERSTATE, new StringType(powerStatus.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (powerStatus == PowerStatus.ON || powerStatus == PowerStatus.WARMUP) {
|
||||||
|
isPowerOn = true;
|
||||||
|
return OnOffType.ON;
|
||||||
|
} else {
|
||||||
|
isPowerOn = false;
|
||||||
|
return OnOffType.OFF;
|
||||||
|
}
|
||||||
|
case POWER_STATE:
|
||||||
|
return null;
|
||||||
|
case SOURCE:
|
||||||
|
return new StringType(remoteController.getSource());
|
||||||
|
case TINT:
|
||||||
|
int tint = remoteController.getTint();
|
||||||
|
return new DecimalType(tint);
|
||||||
|
case VKEYSTONE:
|
||||||
|
int vKeystone = remoteController.getVerticalKeystone();
|
||||||
|
return new DecimalType(vKeystone);
|
||||||
|
case VOLUME:
|
||||||
|
int volume = remoteController.getVolume();
|
||||||
|
return new DecimalType(volume);
|
||||||
|
case VPOSITION:
|
||||||
|
int vPosition = remoteController.getVerticalPosition();
|
||||||
|
return new DecimalType(vPosition);
|
||||||
|
case VREVERSE:
|
||||||
|
Switch vReverse = remoteController.getVerticalReverse();
|
||||||
|
return vReverse == Switch.ON ? OnOffType.ON : OnOffType.OFF;
|
||||||
|
default:
|
||||||
|
logger.warn("Unknown '{}' command!", commandType);
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
} catch (EpsonProjectorCommandException e) {
|
||||||
|
logger.debug("Error executing command '{}', {}", commandType, e.getMessage());
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
} catch (EpsonProjectorException e) {
|
||||||
|
logger.debug("Couldn't execute command '{}', {}", commandType, e.getMessage());
|
||||||
|
closeConnection();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendDataToDevice(EpsonProjectorCommandType commandType, Command command) {
|
||||||
|
EpsonProjectorDevice remoteController = device.get();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!remoteController.isConnected()) {
|
||||||
|
remoteController.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!remoteController.isReady()) {
|
||||||
|
logger.debug("Refusing command '{}' while not ready", commandType.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (commandType) {
|
||||||
|
case AKEYSTONE:
|
||||||
|
remoteController.setAutoKeystone((command == OnOffType.ON ? Switch.ON : Switch.OFF));
|
||||||
|
break;
|
||||||
|
case ASPECT_RATIO:
|
||||||
|
remoteController.setAspectRatio(AspectRatio.valueOf(command.toString()));
|
||||||
|
break;
|
||||||
|
case BACKGROUND:
|
||||||
|
remoteController.setBackground(Background.valueOf(command.toString()));
|
||||||
|
break;
|
||||||
|
case BRIGHTNESS:
|
||||||
|
remoteController.setBrightness(((DecimalType) command).intValue());
|
||||||
|
break;
|
||||||
|
case COLOR_MODE:
|
||||||
|
remoteController.setColorMode(ColorMode.valueOf(command.toString()));
|
||||||
|
break;
|
||||||
|
case COLOR_TEMP:
|
||||||
|
remoteController.setColorTemperature(((DecimalType) command).intValue());
|
||||||
|
break;
|
||||||
|
case CONTRAST:
|
||||||
|
remoteController.setContrast(((DecimalType) command).intValue());
|
||||||
|
break;
|
||||||
|
case DENSITY:
|
||||||
|
remoteController.setDensity(((DecimalType) command).intValue());
|
||||||
|
break;
|
||||||
|
case ERR_CODE:
|
||||||
|
logger.warn("'{}' is read only parameter", commandType);
|
||||||
|
break;
|
||||||
|
case ERR_MESSAGE:
|
||||||
|
logger.warn("'{}' is read only parameter", commandType);
|
||||||
|
break;
|
||||||
|
case FLESH_TEMP:
|
||||||
|
remoteController.setFleshColor(((DecimalType) command).intValue());
|
||||||
|
break;
|
||||||
|
case FREEZE:
|
||||||
|
remoteController.setFreeze(command == OnOffType.ON ? Switch.ON : Switch.OFF);
|
||||||
|
break;
|
||||||
|
case GAMMA:
|
||||||
|
remoteController.setGamma(Gamma.valueOf(command.toString()));
|
||||||
|
break;
|
||||||
|
case HKEYSTONE:
|
||||||
|
remoteController.setHorizontalKeystone(((DecimalType) command).intValue());
|
||||||
|
break;
|
||||||
|
case HPOSITION:
|
||||||
|
remoteController.setHorizontalPosition(((DecimalType) command).intValue());
|
||||||
|
break;
|
||||||
|
case HREVERSE:
|
||||||
|
remoteController.setHorizontalReverse((command == OnOffType.ON ? Switch.ON : Switch.OFF));
|
||||||
|
break;
|
||||||
|
case KEY_CODE:
|
||||||
|
remoteController.sendKeyCode(((DecimalType) command).intValue());
|
||||||
|
break;
|
||||||
|
case LAMP_TIME:
|
||||||
|
logger.warn("'{}' is read only parameter", commandType);
|
||||||
|
break;
|
||||||
|
case LUMINANCE:
|
||||||
|
remoteController.setLuminance(Luminance.valueOf(command.toString()));
|
||||||
|
break;
|
||||||
|
case MUTE:
|
||||||
|
remoteController.setMute((command == OnOffType.ON ? Switch.ON : Switch.OFF));
|
||||||
|
break;
|
||||||
|
case POWER:
|
||||||
|
if (command == OnOffType.ON) {
|
||||||
|
remoteController.setPower(Switch.ON);
|
||||||
|
isPowerOn = true;
|
||||||
|
} else {
|
||||||
|
remoteController.setPower(Switch.OFF);
|
||||||
|
isPowerOn = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case POWER_STATE:
|
||||||
|
logger.warn("'{}' is read only parameter", commandType);
|
||||||
|
break;
|
||||||
|
case SOURCE:
|
||||||
|
remoteController.setSource(command.toString());
|
||||||
|
break;
|
||||||
|
case TINT:
|
||||||
|
remoteController.setTint(((DecimalType) command).intValue());
|
||||||
|
break;
|
||||||
|
case VKEYSTONE:
|
||||||
|
remoteController.setVerticalKeystone(((DecimalType) command).intValue());
|
||||||
|
break;
|
||||||
|
case VOLUME:
|
||||||
|
remoteController.setVolume(((DecimalType) command).intValue());
|
||||||
|
break;
|
||||||
|
case VPOSITION:
|
||||||
|
remoteController.setVerticalPosition(((DecimalType) command).intValue());
|
||||||
|
break;
|
||||||
|
case VREVERSE:
|
||||||
|
remoteController.setVerticalReverse((command == OnOffType.ON ? Switch.ON : Switch.OFF));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logger.warn("Unknown '{}' command!", commandType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (EpsonProjectorCommandException e) {
|
||||||
|
logger.debug("Error executing command '{}', {}", commandType, e.getMessage());
|
||||||
|
} catch (EpsonProjectorException e) {
|
||||||
|
logger.warn("Couldn't execute command '{}', {}", commandType, e.getMessage());
|
||||||
|
closeConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeConnection() {
|
||||||
|
EpsonProjectorDevice remoteController = device.get();
|
||||||
|
try {
|
||||||
|
logger.debug("Closing connection to device '{}'", this.thing.getUID());
|
||||||
|
remoteController.disconnect();
|
||||||
|
updateStatus(ThingStatus.OFFLINE);
|
||||||
|
} catch (EpsonProjectorException e) {
|
||||||
|
logger.debug("Error occurred when closing connection to device '{}'", this.thing.getUID(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<binding:binding id="epsonprojector" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||||
|
|
||||||
|
<name>Epson Projector Binding</name>
|
||||||
|
<description>This binding is compatible with Epson projectors which support the ESC/VP21 protocol</description>
|
||||||
|
|
||||||
|
</binding:binding>
|
@ -0,0 +1,346 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<thing:thing-descriptions bindingId="epsonprojector"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||||
|
|
||||||
|
<thing-type id="projector-serial">
|
||||||
|
<label>Epson Projector - Serial</label>
|
||||||
|
<description>An Epson projector which supports the ESC/VP21 protocol via a serial port connection</description>
|
||||||
|
|
||||||
|
<channels>
|
||||||
|
<channel id="power" typeId="power"/>
|
||||||
|
<channel id="powerstate" typeId="powerstate"/>
|
||||||
|
<channel id="source" typeId="source"/>
|
||||||
|
<channel id="aspectratio" typeId="aspectratio"/>
|
||||||
|
<channel id="colormode" typeId="colormode"/>
|
||||||
|
<channel id="freeze" typeId="freeze"/>
|
||||||
|
<channel id="mute" typeId="mute"/>
|
||||||
|
<channel id="volume" typeId="volume"/>
|
||||||
|
<channel id="luminance" typeId="luminance"/>
|
||||||
|
<channel id="brightness" typeId="brightness"/>
|
||||||
|
<channel id="contrast" typeId="contrast"/>
|
||||||
|
<channel id="density" typeId="density"/>
|
||||||
|
<channel id="tint" typeId="tint"/>
|
||||||
|
<channel id="colortemperature" typeId="colortemperature"/>
|
||||||
|
<channel id="fleshtemperature" typeId="fleshtemperature"/>
|
||||||
|
<channel id="gamma" typeId="gamma"/>
|
||||||
|
<channel id="autokeystone" typeId="autokeystone"/>
|
||||||
|
<channel id="verticalkeystone" typeId="verticalkeystone"/>
|
||||||
|
<channel id="horizontalkeystone" typeId="horizontalkeystone"/>
|
||||||
|
<channel id="verticalposition" typeId="verticalposition"/>
|
||||||
|
<channel id="horizontalposition" typeId="horizontalposition"/>
|
||||||
|
<channel id="verticalreverse" typeId="verticalreverse"/>
|
||||||
|
<channel id="horizontalreverse" typeId="horizontalreverse"/>
|
||||||
|
<channel id="background" typeId="background"/>
|
||||||
|
<channel id="keycode" typeId="keycode"/>
|
||||||
|
<channel id="lamptime" typeId="lamptime"/>
|
||||||
|
<channel id="errcode" typeId="errcode"/>
|
||||||
|
<channel id="errmessage" typeId="errmessage"/>
|
||||||
|
</channels>
|
||||||
|
|
||||||
|
<config-description>
|
||||||
|
<parameter name="serialPort" type="text" required="true">
|
||||||
|
<label>Serial Port</label>
|
||||||
|
<context>serial-port</context>
|
||||||
|
<description>Serial Port to Use for Connecting to the Epson Projector</description>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="pollingInterval" type="integer" min="5" max="60" unit="s" required="false">
|
||||||
|
<label>Polling interval</label>
|
||||||
|
<description>Configures How Often to Poll the Projector for Updates (5-60; Default 10)</description>
|
||||||
|
<default>10</default>
|
||||||
|
</parameter>
|
||||||
|
</config-description>
|
||||||
|
|
||||||
|
</thing-type>
|
||||||
|
|
||||||
|
<thing-type id="projector-tcp">
|
||||||
|
<label>Epson Projector - TCP/IP</label>
|
||||||
|
<description>An Epson projector which supports the ESC/VP21 protocol via a serial over IP connection</description>
|
||||||
|
|
||||||
|
<channels>
|
||||||
|
<channel id="power" typeId="power"/>
|
||||||
|
<channel id="powerstate" typeId="powerstate"/>
|
||||||
|
<channel id="source" typeId="source"/>
|
||||||
|
<channel id="aspectratio" typeId="aspectratio"/>
|
||||||
|
<channel id="colormode" typeId="colormode"/>
|
||||||
|
<channel id="freeze" typeId="freeze"/>
|
||||||
|
<channel id="mute" typeId="mute"/>
|
||||||
|
<channel id="volume" typeId="volume"/>
|
||||||
|
<channel id="luminance" typeId="luminance"/>
|
||||||
|
<channel id="brightness" typeId="brightness"/>
|
||||||
|
<channel id="contrast" typeId="contrast"/>
|
||||||
|
<channel id="density" typeId="density"/>
|
||||||
|
<channel id="tint" typeId="tint"/>
|
||||||
|
<channel id="colortemperature" typeId="colortemperature"/>
|
||||||
|
<channel id="fleshtemperature" typeId="fleshtemperature"/>
|
||||||
|
<channel id="gamma" typeId="gamma"/>
|
||||||
|
<channel id="autokeystone" typeId="autokeystone"/>
|
||||||
|
<channel id="verticalkeystone" typeId="verticalkeystone"/>
|
||||||
|
<channel id="horizontalkeystone" typeId="horizontalkeystone"/>
|
||||||
|
<channel id="verticalposition" typeId="verticalposition"/>
|
||||||
|
<channel id="horizontalposition" typeId="horizontalposition"/>
|
||||||
|
<channel id="verticalreverse" typeId="verticalreverse"/>
|
||||||
|
<channel id="horizontalreverse" typeId="horizontalreverse"/>
|
||||||
|
<channel id="background" typeId="background"/>
|
||||||
|
<channel id="keycode" typeId="keycode"/>
|
||||||
|
<channel id="lamptime" typeId="lamptime"/>
|
||||||
|
<channel id="errcode" typeId="errcode"/>
|
||||||
|
<channel id="errmessage" typeId="errmessage"/>
|
||||||
|
</channels>
|
||||||
|
|
||||||
|
<config-description>
|
||||||
|
<parameter name="host" type="text" required="true">
|
||||||
|
<label>Host</label>
|
||||||
|
<context>network-address</context>
|
||||||
|
<description>IP address for the serial over IP device</description>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="port" type="integer" min="1" max="65535" required="true">
|
||||||
|
<label>Port</label>
|
||||||
|
<description>Port for the serial over IP device</description>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="pollingInterval" type="integer" min="5" max="60" unit="s" required="false">
|
||||||
|
<label>Polling interval</label>
|
||||||
|
<description>Configures How Often to Poll the Projector for Updates (5-60; Default 10)</description>
|
||||||
|
<default>10</default>
|
||||||
|
</parameter>
|
||||||
|
</config-description>
|
||||||
|
|
||||||
|
</thing-type>
|
||||||
|
|
||||||
|
<channel-type id="power">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>Power</label>
|
||||||
|
<description>Powers the Projector On or Off</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="powerstate">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Power State</label>
|
||||||
|
<description>Retrieves the Textual Power State of the Projector</description>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="lamptime">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Lamp Time</label>
|
||||||
|
<description>Retrieves the Lamp Hours</description>
|
||||||
|
<state readOnly="true" pattern="%d h"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="keycode" advanced="true">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>KeyCode</label>
|
||||||
|
<description>Send a KEY Operation Command to the Projector</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="verticalkeystone" advanced="true">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Vertical Keystone</label>
|
||||||
|
<description>Retrieve or Set the Vertical Keystone</description>
|
||||||
|
<state min="-30" max="30" step="1" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="horizontalkeystone" advanced="true">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Horizontal Keystone</label>
|
||||||
|
<description>Retrieve or Set the Horizontal Keystone</description>
|
||||||
|
<state min="-30" max="30" step="1" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="autokeystone" advanced="true">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>Auto Keystone</label>
|
||||||
|
<description>Turn the Auto Keystone On or Off</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="freeze">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>Freeze Image</label>
|
||||||
|
<description>Turn the Freeze Screen Mode On or Off</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="aspectratio">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Aspect Ratio</label>
|
||||||
|
<description>Retrieve or Set the Aspect Ratio</description>
|
||||||
|
<state>
|
||||||
|
<options>
|
||||||
|
<option value="NORMAL">NORMAL</option>
|
||||||
|
<option value="AUTO">AUTO</option>
|
||||||
|
<option value="FULL">FULL</option>
|
||||||
|
<option value="ZOOM">ZOOM</option>
|
||||||
|
<option value="WIDE">WIDE</option>
|
||||||
|
<option value="ANAMORPHIC">ANAMORPHIC</option>
|
||||||
|
<option value="SQUEEZE">SQUEEZE</option>
|
||||||
|
<option value="RATIO4X3">RATIO4X3</option>
|
||||||
|
<option value="ZOOM4X3">ZOOM4X3</option>
|
||||||
|
<option value="RATIO16X9">RATIO16X9</option>
|
||||||
|
<option value="UP16X9">UP16X9</option>
|
||||||
|
<option value="DOWN16X9">DOWN16X9</option>
|
||||||
|
<option value="REAL">REAL</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="luminance">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Luminance</label>
|
||||||
|
<description>Retrieve or Set the Lamp Mode</description>
|
||||||
|
<state>
|
||||||
|
<options>
|
||||||
|
<option value="NORMAL">NORMAL</option>
|
||||||
|
<option value="ECO">ECO</option>
|
||||||
|
<option value="MEDIUM">MEDIUM</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="source">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Source</label>
|
||||||
|
<description>Retrieve or Set the Input Source</description>
|
||||||
|
<state>
|
||||||
|
<options>
|
||||||
|
<option value="30">HDMI1</option>
|
||||||
|
<option value="A0">HDMI2</option>
|
||||||
|
<option value="14">Component</option>
|
||||||
|
<option value="20">PC DSUB</option>
|
||||||
|
<option value="41">Video</option>
|
||||||
|
<option value="42">S-Video</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="brightness" advanced="true">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Brightness</label>
|
||||||
|
<description>Retrieve or Set the Brightness</description>
|
||||||
|
<state min="-24" max="24" step="1" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="contrast" advanced="true">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Contrast</label>
|
||||||
|
<description>Retrieve or Set the Contrast</description>
|
||||||
|
<state min="-24" max="24" step="1" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="density" advanced="true">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Density (Color Saturation)</label>
|
||||||
|
<description>Retrieve or Set the Density</description>
|
||||||
|
<state min="-32" max="32" step="1" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="tint" advanced="true">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Tint</label>
|
||||||
|
<description>Retrieve or Set the Tint</description>
|
||||||
|
<state min="-32" max="32" step="1" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="colortemperature" advanced="true">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Color Temperature</label>
|
||||||
|
<description>Retrieve or Set the Color Temperature</description>
|
||||||
|
<state min="0" max="9" step="1" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="fleshtemperature" advanced="true">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Flesh Temperature</label>
|
||||||
|
<description>Retrieve or Set the Flesh Temperature</description>
|
||||||
|
<state min="0" max="6" step="1" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="colormode">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Color Mode</label>
|
||||||
|
<description>Retrieve or Set the Color Mode</description>
|
||||||
|
<state>
|
||||||
|
<options>
|
||||||
|
<option value="DYNAMIC">DYNAMIC</option>
|
||||||
|
<option value="LIVINGROOM">LIVINGROOM</option>
|
||||||
|
<option value="NATURAL">NATURAL</option>
|
||||||
|
<option value="CINEMA">CINEMA</option>
|
||||||
|
<option value="CINEMANIGHT">CINEMANIGHT</option>
|
||||||
|
<option value="BWCINEMA">BWCINEMA</option>
|
||||||
|
<option value="DIGITALCINEMA">DIGITALCINEMA</option>
|
||||||
|
<option value="HD">HD</option>
|
||||||
|
<option value="THX">THX</option>
|
||||||
|
<option value="CINEMA3D">CINEMA3D</option>
|
||||||
|
<option value="DYNAMIC3D">DYNAMIC3D</option>
|
||||||
|
<option value="THX3D">THX3D</option>
|
||||||
|
<option value="SRGB">SRGB</option>
|
||||||
|
<option value="NORMAL">NORMAL</option>
|
||||||
|
<option value="MEETING">MEETING</option>
|
||||||
|
<option value="PRESENTATION">PRESENTATION</option>
|
||||||
|
<option value="SPORTS">SPORTS</option>
|
||||||
|
<option value="CUSTOM">CUSTOM</option>
|
||||||
|
<option value="BLACKBOARD">BLACKBOARD</option>
|
||||||
|
<option value="WHITEBOARD">WHITEBOARD</option>
|
||||||
|
<option value="PHOTO">PHOTO</option>
|
||||||
|
<option value="SILVER">SILVER</option>
|
||||||
|
<option value="XVCOLOR">XVCOLOR</option>
|
||||||
|
<option value="DICOMSIM">DICOMSIM</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="horizontalposition" advanced="true">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Horizontal Position</label>
|
||||||
|
<description>Retrieve or Set the Horizontal Position</description>
|
||||||
|
<state min="-23" max="26" step="1" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="verticalposition" advanced="true">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Vertical Position</label>
|
||||||
|
<description>Retrieve or Set the Vertical Position</description>
|
||||||
|
<state min="-8" max="10" step="1" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="gamma" advanced="true">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Gamma</label>
|
||||||
|
<description>Retrieve or Set the Gamma Setting</description>
|
||||||
|
<state>
|
||||||
|
<options>
|
||||||
|
<option value="G2_0">G2_0</option>
|
||||||
|
<option value="G2_1">G2_1</option>
|
||||||
|
<option value="G2_2">G2_2</option>
|
||||||
|
<option value="G2_3">G2_3</option>
|
||||||
|
<option value="G2_4">G2_4</option>
|
||||||
|
<option value="CUSTOM">CUSTOM</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="volume">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>Volume</label>
|
||||||
|
<description>Retrieve or Set the Volume</description>
|
||||||
|
<state min="0" max="20" step="1" pattern="%d"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="mute">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>AV Mute</label>
|
||||||
|
<description>Turn the AV Mute On or Off</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="horizontalreverse" advanced="true">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>Horizontal Reverse</label>
|
||||||
|
<description>Turn the Horizontal Reverse On or Off</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="verticalreverse" advanced="true">
|
||||||
|
<item-type>Switch</item-type>
|
||||||
|
<label>Vertical Reverse</label>
|
||||||
|
<description>Turn the Vertical Reverse On or Off</description>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="background" advanced="true">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Background</label>
|
||||||
|
<description>Select the Background Color/Logo</description>
|
||||||
|
<state>
|
||||||
|
<options>
|
||||||
|
<option value="BLACK">BLACK</option>
|
||||||
|
<option value="BLUE">BLUE</option>
|
||||||
|
<option value="LOGO">LOGO</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="errcode" advanced="true">
|
||||||
|
<item-type>Number</item-type>
|
||||||
|
<label>ErrCode</label>
|
||||||
|
<description>Retrieves the Last Error Code</description>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="errmessage" advanced="true">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>ErrMessage</label>
|
||||||
|
<description>Retrieves the Description of the Last Error</description>
|
||||||
|
<state readOnly="true"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
</thing:thing-descriptions>
|
@ -95,6 +95,7 @@
|
|||||||
<module>org.openhab.binding.enigma2</module>
|
<module>org.openhab.binding.enigma2</module>
|
||||||
<module>org.openhab.binding.enocean</module>
|
<module>org.openhab.binding.enocean</module>
|
||||||
<module>org.openhab.binding.enturno</module>
|
<module>org.openhab.binding.enturno</module>
|
||||||
|
<module>org.openhab.binding.epsonprojector</module>
|
||||||
<module>org.openhab.binding.etherrain</module>
|
<module>org.openhab.binding.etherrain</module>
|
||||||
<module>org.openhab.binding.evohome</module>
|
<module>org.openhab.binding.evohome</module>
|
||||||
<module>org.openhab.binding.exec</module>
|
<module>org.openhab.binding.exec</module>
|
||||||
|
Loading…
Reference in New Issue
Block a user