[sonyprojector] Add new channel to send infrared remote commands (#15753)

Fix #15409

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
lolodomo 2023-12-12 23:20:10 +01:00 committed by GitHub
parent 2be0f8dd66
commit 3972dde690
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 884 additions and 194 deletions

View File

@ -187,6 +187,128 @@ The following channels are available:
| overscan | Overscan | Switch | RW | Hide or not the edges of the picture | ON, OFF |
| pictureposition | Picture Position | String | RW | Adjust the picture position | 185, 235, Custom1, Custom2, Custom3, Position1, Position2, Position3, Position4, Position5 |
| lampusetime | Lamp Use Time | Number | R | Indicate how long the lamp has been turned on | |
| ircommand | IR Command | String | W | Send an infrared remote command | |
Here is the list of infrared remote commands you can use, some of them will work only on particular models.
| Command | Description |
| ------------------- | ------------------------- |
| POWER | Power On/Off |
| POWER_ON | Power On |
| POWER_OFF | Power Off |
| INPUT | Video Input |
| INPUT_DVI | DVI |
| INPUT_HDMI | HDMI |
| INPUT_HDMI1 | HDMI 1 |
| INPUT_HDMI2 | HDMI 2 |
| INPUT_COMPONENT | Component |
| INPUT_SVIDEO | S-Video |
| INPUT_VIDEO | Video |
| INPUT_INPUTA | Input A |
| CALIBRATION_PRESET | Calibration preset |
| PRESET_REFERENCE | Reference |
| PRESET_TV | TV |
| PRESET_PHOTO | Photo |
| PRESET_GAME | Game |
| PRESET_DYNAMIC | Dynamic |
| PRESET_STANDARD | Standard |
| PRESET_CINEMA | Cinema |
| PRESET_CINEMA1 | Cinema 1 |
| PRESET_CINEMA2 | Cinema 2 |
| PRESET_CINEMA3 | Cinema 3 |
| PRESET_DIGITAL | Cinema Digital |
| PRESET_FILM1 | Cinema Film 1 |
| PRESET_FILM2 | Cinema Film 2 |
| PRESET_BRTCINE | Bright Cinema |
| PRESET_BRTTV | Bright TV |
| PRESET_USER | User |
| PRESET_USER1 | User 1 |
| PRESET_USER2 | User 2 |
| PRESET_USER3 | User 3 |
| CONTRAST_UP | Contrast + |
| CONTRAST_DOWN | Contrast - |
| BRIGHTNESS_UP | Brightness + |
| BRIGHTNESS_DOWN | Brightness - |
| COLOR_UP | Color + |
| COLOR_DOWN | Color - |
| HUE_UP | Hue + |
| HUE_DOWN | Hue - |
| SHARPNESS_UP | Sharpness + |
| SHARPNESS_DOWN | Sharpness - |
| CONTRAST_ENHANCER | Contrast Enhancer |
| COLOR_TEMP | Color Temperature |
| GAMMA_CORRECTION | Gamma Correction |
| COLOR_SPACE | Color Space |
| PICTURE_MUTING | Picture Muting |
| REAL_COLOR | Real Color Processing |
| REALITY_CREATION | Reality Creation |
| FILM_PROJECTION | Film Projection |
| MOTION_ENHANCER | Motion Enhancer |
| IRIS_MODE | Iris Mode |
| ASPECT | Aspect Ratio |
| ASPECT_NORMAL | Normal |
| ASPECT_FULL | Full |
| ASPECT_FULL1 | Full 1 |
| ASPECT_FULL2 | Full 2 |
| ASPECT_ZOOM | Zoom |
| ASPECT_WIDEZOOM | Wide Zoom |
| ASPECT_VSTRETCH | V Stretch |
| ASPECT_STRETCH | Stretch |
| ASPECT_SQUEEZE | Squeeze |
| ASPECT_185 | 1.85:1 Zoom |
| ASPECT_235 | 2.35:1 Zoom |
| ASPECT_ANAMORPHIC | Anamorphic |
| ASPECT_SUBTITLE | Subtitle |
| PICTURE_POS_185 | Picture Position 1.85:1 |
| PICTURE_POS_235 | Picture Position 2.35:1 |
| PICTURE_POS_CUSTOM1 | Picture Position Custom 1 |
| PICTURE_POS_CUSTOM2 | Picture Position Custom 2 |
| PICTURE_POS_CUSTOM3 | Picture Position Custom 3 |
| MENU | Menu |
| UP | Cursor UP |
| DOWN | Cursor DOWN |
| LEFT | Cursor LEFT |
| RIGHT | Cursor RIGHT |
| ENTER | Enter |
| RESET | Reset |
| MEMORY | Memory |
| STATUS_ON | Status On |
| STATUS_OFF | Status Off |
| ADJUST_PICTURE | Adjust Picture |
| COLOR_CORRECTION | Color Correction |
| PITCH | Screen Pitch |
| SHIFT | Screen Shift |
| APA | APA |
| DOT_PHASE | Dot Phase |
| V_KEYSTONE | V Keystone |
| V_KEYSTONE_UP | V Keystone + |
| V_KEYSTONE_DOWN | V Keystone - |
| LENS_CONTROL | Lens Control |
| LENS_SHIFT | Lens Shift |
| LENS_SHIFT_LEFT | Lens Shift LEFT |
| LENS_SHIFT_RIGHT | Lens Shift RIGHT |
| LENS_SHIFT_UP | Lens Shift UP |
| LENS_SHIFT_DOWN | Lens Shift DOWN |
| LENS_ZOOM | Lens Zoom |
| LENS_ZOOM_LARGE | Lens Zoom Large |
| LENS_ZOOM_SMALL | Lens Zoom Small |
| LENS_FOCUS | Lens Focus |
| LENS_FOCUS_FAR | Lens Focus Far |
| LENS_FOCUS_NEAR | Lens Focus Near |
| LENS_POSITION | Lens Position |
| MODE_3D | 3D |
| OPTIONS | Options |
| EXIT | Exit |
| SYNC_MENU | Sync Menu |
| PLAY | Play |
| STOP | Stop |
| PAUSE | Pause |
| FAST_REWIND( | Fast Rewind |
| FAST_FORWARD | Fast Forward |
| PREVIOUS | Previous |
| NEXT | Next |
In case you know an infrared remote command not listed in this list and you know its hexadecimal code, you can send the hexadecimal value directly; it must be 4 characters started with either 17, 19 or 1B.
## Full Example

View File

@ -63,4 +63,5 @@ public class SonyProjectorBindingConstants {
public static final String CHANNEL_OVERSCAN = "overscan";
public static final String CHANNEL_PICTURE_POSITION = "pictureposition";
public static final String CHANNEL_LAMP_USE_TIME = "lampusetime";
public static final String CHANNEL_IR_COMMAND = "ircommand";
}

View File

@ -0,0 +1,42 @@
/**
* Copyright (c) 2010-2023 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.sonyprojector.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.events.EventPublisher;
import org.openhab.core.thing.binding.BaseDynamicCommandDescriptionProvider;
import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
import org.openhab.core.thing.link.ItemChannelLinkRegistry;
import org.openhab.core.thing.type.DynamicCommandDescriptionProvider;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* Dynamic provider of command options while leaving other command description fields as original.
*
* @author Laurent Garnier - Initial contribution
*/
@Component(service = { DynamicCommandDescriptionProvider.class, SonyProjectorCommandDescriptionOptionProvider.class })
@NonNullByDefault
public class SonyProjectorCommandDescriptionOptionProvider extends BaseDynamicCommandDescriptionProvider {
@Activate
public SonyProjectorCommandDescriptionOptionProvider(final @Reference EventPublisher eventPublisher, //
final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry, //
final @Reference ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
this.eventPublisher = eventPublisher;
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService;
}
}

View File

@ -50,14 +50,17 @@ public class SonyProjectorHandlerFactory extends BaseThingHandlerFactory {
private final SerialPortManager serialPortManager;
private final SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider;
private final SonyProjectorCommandDescriptionOptionProvider commandDescriptionProvider;
private final TranslationProvider i18nProvider;
@Activate
public SonyProjectorHandlerFactory(final @Reference SerialPortManager serialPortManager,
final @Reference SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider,
final @Reference SonyProjectorCommandDescriptionOptionProvider commandDescriptionProvider,
final @Reference TranslationProvider i18nProvider) {
this.serialPortManager = serialPortManager;
this.stateDescriptionProvider = stateDescriptionProvider;
this.commandDescriptionProvider = commandDescriptionProvider;
this.i18nProvider = i18nProvider;
}
@ -71,7 +74,8 @@ public class SonyProjectorHandlerFactory extends BaseThingHandlerFactory {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) {
return new SonyProjectorHandler(thing, stateDescriptionProvider, serialPortManager, i18nProvider);
return new SonyProjectorHandler(thing, stateDescriptionProvider, commandDescriptionProvider,
serialPortManager, i18nProvider);
}
return null;

View File

@ -36,6 +36,7 @@ import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorMot
import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorMpegNr;
import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorNr;
import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorPicturePosition;
import org.openhab.core.types.CommandOption;
import org.openhab.core.types.StateOption;
/**
@ -239,6 +240,15 @@ public enum SonyProjectorModel {
return SonyProjectorCalibrationPreset.getStateOptions(calibrPresetsCategory);
}
/**
* Get the list of {@link CommandOption} associated to the available calibration presets
*
* @return the list of {@link CommandOption} associated to the available calibration presets
*/
public List<CommandOption> getCalibrPresetCommandOptions() {
return SonyProjectorCalibrationPreset.getCommandOptions(calibrPresetsCategory);
}
/**
* Get the calibration preset associated to a name
*
@ -248,8 +258,8 @@ public enum SonyProjectorModel {
*
* @throws SonyProjectorException - If no calibration preset is associated to the searched name
*/
public byte[] getCalibrPresetDataCodeFromName(String name) throws SonyProjectorException {
return SonyProjectorCalibrationPreset.getFromName(calibrPresetsCategory, name).getDataCode();
public SonyProjectorCalibrationPreset getCalibrPresetFromName(String name) throws SonyProjectorException {
return SonyProjectorCalibrationPreset.getFromName(calibrPresetsCategory, name);
}
/**
@ -274,6 +284,15 @@ public enum SonyProjectorModel {
return SonyProjectorInput.getStateOptions(inputCategory);
}
/**
* Get the list of {@link CommandOption} associated to the available video inputs
*
* @return the list of {@link CommandOption} associated to the available video inputs
*/
public List<CommandOption> getInputCommandOptions() {
return SonyProjectorInput.getCommandOptions(inputCategory);
}
/**
* Get the video input associated to a name
*
@ -283,8 +302,8 @@ public enum SonyProjectorModel {
*
* @throws SonyProjectorException - If no video input is associated to the searched name
*/
public byte[] getInputDataCodeFromName(String name) throws SonyProjectorException {
return SonyProjectorInput.getFromName(inputCategory, name).getDataCode();
public SonyProjectorInput getInputFromName(String name) throws SonyProjectorException {
return SonyProjectorInput.getFromName(inputCategory, name);
}
/**
@ -450,6 +469,15 @@ public enum SonyProjectorModel {
return SonyProjectorAspect.getStateOptions(aspectCategory);
}
/**
* Get the list of {@link CommandOption} associated to the available aspect modes
*
* @return the list of {@link CommandOption} associated to the available aspect modes
*/
public List<CommandOption> getAspectCommandOptions() {
return SonyProjectorAspect.getCommandOptions(aspectCategory);
}
/**
* Get the aspect mode associated to a name
*
@ -459,8 +487,8 @@ public enum SonyProjectorModel {
*
* @throws SonyProjectorException - If no aspect mode is associated to the searched name
*/
public byte[] getAspectCodeFromName(String name) throws SonyProjectorException {
return SonyProjectorAspect.getFromName(aspectCategory, name).getDataCode();
public SonyProjectorAspect getAspectFromName(String name) throws SonyProjectorException {
return SonyProjectorAspect.getFromName(aspectCategory, name);
}
/**

View File

@ -18,6 +18,7 @@ import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.sonyprojector.internal.SonyProjectorException;
import org.openhab.core.types.CommandOption;
import org.openhab.core.types.StateOption;
import org.openhab.core.util.HexUtils;
@ -30,56 +31,57 @@ import org.openhab.core.util.HexUtils;
public enum SonyProjectorAspect {
// Category 1: VW260, VW270, VW285, VW295, VW300, VW315, VW320, VW328, VW350, VW365, VW385, VW500, VW515, VW520,
// VW528, VW550, VW570, VW600, VW665, VW675, VW695, VW760, VW885
CAT1_NORMAL(1, "Normal", new byte[] { 0x00, 0x01 }),
CAT1_V_STRETCH(1, "VStretch", new byte[] { 0x00, 0x0B }),
CAT1_185(1, "185", new byte[] { 0x00, 0x0C }),
CAT1_235(1, "235", new byte[] { 0x00, 0x0D }),
CAT1_STRETCH(1, "Stretch", new byte[] { 0x00, 0x0E }),
CAT1_SQUEEZE(1, "Squeeze", new byte[] { 0x00, 0x0F }),
// VW528, VW550, VW570, VW600, VW665, VW675, VW695, VW760, VW885, VW1000ES, VW1100ES
CAT1_NORMAL(1, "Normal", new byte[] { 0x00, 0x01 }, new byte[] { 0x1B, 0x41 }),
CAT1_V_STRETCH(1, "VStretch", new byte[] { 0x00, 0x0B }, new byte[] { 0x1B, 0x44 }),
CAT1_185(1, "185", new byte[] { 0x00, 0x0C }, new byte[] { 0x1B, 0x45 }),
CAT1_235(1, "235", new byte[] { 0x00, 0x0D }, new byte[] { 0x1B, 0x46 }),
CAT1_STRETCH(1, "Stretch", new byte[] { 0x00, 0x0E }, new byte[] { 0x1B, 0x47 }),
CAT1_SQUEEZE(1, "Squeeze", new byte[] { 0x00, 0x0F }, new byte[] { 0x1B, 0x48 }),
// Category 2: VW40, VW50, HW10, HW15, HW20, HW30
CAT2_FULL(2, "Full", new byte[] { 0x00, 0x00 }),
CAT2_NORMAL(2, "Normal", new byte[] { 0x00, 0x01 }),
CAT2_WIDE(2, "WideZoom", new byte[] { 0x00, 0x02 }),
CAT2_ZOOM(2, "Zoom", new byte[] { 0x00, 0x03 }),
CAT2_FULL1(2, "Full1", new byte[] { 0x00, 0x07 }),
CAT2_FULL2(2, "Full2", new byte[] { 0x00, 0x08 }),
CAT2_FULL(2, "Full", new byte[] { 0x00, 0x00 }, new byte[] { 0x1B, 0x42 }),
CAT2_NORMAL(2, "Normal", new byte[] { 0x00, 0x01 }, new byte[] { 0x1B, 0x41 }),
CAT2_WIDE(2, "WideZoom", new byte[] { 0x00, 0x02 }, new byte[] { 0x1B, 0x3E }),
CAT2_ZOOM(2, "Zoom", new byte[] { 0x00, 0x03 }, new byte[] { 0x1B, 0x43 }),
CAT2_FULL1(2, "Full1", new byte[] { 0x00, 0x07 }, new byte[] { 0x1B, 0x3F }),
CAT2_FULL2(2, "Full2", new byte[] { 0x00, 0x08 }, new byte[] { 0x1B, 0x40 }),
// Category 3: VW60, VW70, VW80, VW85, VW90, VW95, VW200
CAT3_FULL(3, "Full", new byte[] { 0x00, 0x00 }),
CAT3_NORMAL(3, "Normal", new byte[] { 0x00, 0x01 }),
CAT3_WIDE(3, "WideZoom", new byte[] { 0x00, 0x02 }),
CAT3_ZOOM(3, "Zoom", new byte[] { 0x00, 0x03 }),
CAT3_FULL1(3, "Full1", new byte[] { 0x00, 0x07 }),
CAT3_FULL2(3, "Full2", new byte[] { 0x00, 0x08 }),
CAT3_ANAMORPHIC(3, "Anamorphic", new byte[] { 0x00, 0x0B }),
CAT3_FULL(3, "Full", new byte[] { 0x00, 0x00 }, new byte[] { 0x1B, 0x42 }),
CAT3_NORMAL(3, "Normal", new byte[] { 0x00, 0x01 }, new byte[] { 0x1B, 0x41 }),
CAT3_WIDE(3, "WideZoom", new byte[] { 0x00, 0x02 }, new byte[] { 0x1B, 0x3E }),
CAT3_ZOOM(3, "Zoom", new byte[] { 0x00, 0x03 }, new byte[] { 0x1B, 0x43 }),
CAT3_FULL1(3, "Full1", new byte[] { 0x00, 0x07 }, new byte[] { 0x1B, 0x3F }),
CAT3_FULL2(3, "Full2", new byte[] { 0x00, 0x08 }, new byte[] { 0x1B, 0x40 }),
CAT3_ANAMORPHIC(3, "Anamorphic", new byte[] { 0x00, 0x0B }, new byte[] { 0x1B, 0x44 }),
// Category 4: VW100
CAT4_FULL(4, "Full", new byte[] { 0x00, 0x00 }),
CAT4_NORMAL(4, "Normal", new byte[] { 0x00, 0x01 }),
CAT4_WIDE(4, "WideZoom", new byte[] { 0x00, 0x02 }),
CAT4_ZOOM(4, "Zoom", new byte[] { 0x00, 0x03 }),
CAT3_SUBTITLE(4, "Subtitle", new byte[] { 0x00, 0x04 }),
CAT4_FULL(4, "Full", new byte[] { 0x00, 0x00 }, new byte[] { 0x1B, 0x42 }),
CAT4_NORMAL(4, "Normal", new byte[] { 0x00, 0x01 }, new byte[] { 0x1B, 0x41 }),
CAT4_WIDE(4, "WideZoom", new byte[] { 0x00, 0x02 }, new byte[] { 0x1B, 0x3E }),
CAT4_ZOOM(4, "Zoom", new byte[] { 0x00, 0x03 }, new byte[] { 0x1B, 0x43 }),
CAT3_SUBTITLE(4, "Subtitle", new byte[] { 0x00, 0x04 }, new byte[] { 0x1B, 0x49 }), // IR code not confirmed
// Category 5: HW40ES, HW50ES, HW55ES, HW58ES
CAT5_FULL(5, "Full", new byte[] { 0x00, 0x00 }),
CAT5_NORMAL(5, "Normal", new byte[] { 0x00, 0x01 }),
CAT5_WIDE(5, "WideZoom", new byte[] { 0x00, 0x02 }),
CAT5_ZOOM(5, "Zoom", new byte[] { 0x00, 0x03 }),
CAT5_V_STRETCH(5, "VStretch", new byte[] { 0x00, 0x0B }),
CAT5_STRETCH(5, "Stretch", new byte[] { 0x00, 0x0E }),
CAT5_SQUEEZE(5, "Squeeze", new byte[] { 0x00, 0x0F }),
CAT5_FULL(5, "Full", new byte[] { 0x00, 0x00 }, new byte[] { 0x1B, 0x42 }),
CAT5_NORMAL(5, "Normal", new byte[] { 0x00, 0x01 }, new byte[] { 0x1B, 0x41 }),
CAT5_WIDE(5, "WideZoom", new byte[] { 0x00, 0x02 }, new byte[] { 0x1B, 0x3E }),
CAT5_ZOOM(5, "Zoom", new byte[] { 0x00, 0x03 }, new byte[] { 0x1B, 0x43 }),
CAT5_V_STRETCH(5, "VStretch", new byte[] { 0x00, 0x0B }, new byte[] { 0x1B, 0x44 }),
CAT5_STRETCH(5, "Stretch", new byte[] { 0x00, 0x0E }, new byte[] { 0x1B, 0x47 }),
CAT5_SQUEEZE(5, "Squeeze", new byte[] { 0x00, 0x0F }, new byte[] { 0x1B, 0x48 }),
// Category 6: HW45ES, HW60, HW65, HW68
CAT6_NORMAL(6, "Normal", new byte[] { 0x00, 0x01 }),
CAT6_V_STRETCH(6, "VStretch", new byte[] { 0x00, 0x0B }),
CAT6_STRETCH(6, "Stretch", new byte[] { 0x00, 0x0E }),
CAT6_SQUEEZE(6, "Squeeze", new byte[] { 0x00, 0x0F });
CAT6_NORMAL(6, "Normal", new byte[] { 0x00, 0x01 }, new byte[] { 0x1B, 0x41 }),
CAT6_V_STRETCH(6, "VStretch", new byte[] { 0x00, 0x0B }, new byte[] { 0x1B, 0x44 }),
CAT6_STRETCH(6, "Stretch", new byte[] { 0x00, 0x0E }, new byte[] { 0x1B, 0x47 }),
CAT6_SQUEEZE(6, "Squeeze", new byte[] { 0x00, 0x0F }, new byte[] { 0x1B, 0x48 });
private int category;
private String name;
private byte[] dataCode;
private byte[] irCode;
/**
* Constructor
@ -87,11 +89,13 @@ public enum SonyProjectorAspect {
* @param category a category of projector models for which the aspect mode is available
* @param name the name of the aspect mode
* @param dataCode the data code identifying the aspect mode
* @param irCode the IR code for the aspect mode
*/
private SonyProjectorAspect(int category, String name, byte[] dataCode) {
private SonyProjectorAspect(int category, String name, byte[] dataCode, byte[] irCode) {
this.category = category;
this.name = name;
this.dataCode = dataCode;
this.irCode = irCode;
}
/**
@ -112,6 +116,15 @@ public enum SonyProjectorAspect {
return dataCode;
}
/**
* Get the IR code for the current aspect mode
*
* @return the IR code
*/
public byte[] getIrCode() {
return irCode;
}
/**
* Get the name of the current aspect mode
*
@ -140,6 +153,26 @@ public enum SonyProjectorAspect {
return options;
}
/**
* Get the list of {@link CommandOption} associated to the available aspect modes for a particular category of
* projector models
*
* @param category a category of projector models
*
* @return the list of {@link CommandOption} associated to the available aspect modes for a provided category of
* projector models
*/
public static List<CommandOption> getCommandOptions(int category) {
List<CommandOption> options = new ArrayList<>();
for (SonyProjectorAspect value : SonyProjectorAspect.values()) {
if (value.getCategory() == category) {
options.add(new CommandOption("ASPECT_" + value.getName().toUpperCase(),
"@text/channel-type.sonyprojector.aspect.state.option." + value.getName()));
}
}
return options;
}
/**
* Get the aspect mode associated to a name for a particular category of projector models
*
@ -152,7 +185,7 @@ public enum SonyProjectorAspect {
*/
public static SonyProjectorAspect getFromName(int category, String name) throws SonyProjectorException {
for (SonyProjectorAspect value : SonyProjectorAspect.values()) {
if (value.getCategory() == category && value.getName().equals(name)) {
if (value.getCategory() == category && value.getName().equalsIgnoreCase(name)) {
return value;
}
}

View File

@ -18,6 +18,7 @@ import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.sonyprojector.internal.SonyProjectorException;
import org.openhab.core.types.CommandOption;
import org.openhab.core.types.StateOption;
import org.openhab.core.util.HexUtils;
@ -33,57 +34,58 @@ public enum SonyProjectorCalibrationPreset {
// Category 1: VW260, VW270, VW285, VW295, VW300, VW315, VW320, VW328, VW350, VW365, VW385, VW500, VW515, VW520,
// VW528, VW550, VW570, VW600, VW665, VW675, VW695, VW760, VW870, VW885, VW995, HW40ES, HW45ES, HW50ES, HW55ES,
// HW58ES, HW60, HW65, HW68
CAT1_CINEMA_FILM1(1, "Film1", new byte[] { 0x00, 0x00 }),
CAT1_CINEMA_FILM2(1, "Film2", new byte[] { 0x00, 0x01 }),
CAT1_REFERENCE(1, "Reference", new byte[] { 0x00, 0x02 }),
CAT1_TV(1, "TV", new byte[] { 0x00, 0x03 }),
CAT1_PHOTO(1, "Photo", new byte[] { 0x00, 0x04 }),
CAT1_GAME(1, "Game", new byte[] { 0x00, 0x05 }),
CAT1_BRT_CINE(1, "BRTCINE", new byte[] { 0x00, 0x06 }),
CAT1_BRT_TV(1, "BRTTV", new byte[] { 0x00, 0x07 }),
CAT1_USER(1, "User", new byte[] { 0x00, 0x08 }),
CAT1_CINEMA_FILM1(1, "Film1", new byte[] { 0x00, 0x00 }, new byte[] { 0x19, 0x53 }),
CAT1_CINEMA_FILM2(1, "Film2", new byte[] { 0x00, 0x01 }, new byte[] { 0x19, 0x58 }),
CAT1_REFERENCE(1, "Reference", new byte[] { 0x00, 0x02 }, new byte[] { 0x19, 0x55 }),
CAT1_TV(1, "TV", new byte[] { 0x00, 0x03 }, new byte[] { 0x19, 0x52 }),
CAT1_PHOTO(1, "Photo", new byte[] { 0x00, 0x04 }, new byte[] { 0x19, 0x57 }),
CAT1_GAME(1, "Game", new byte[] { 0x00, 0x05 }, new byte[] { 0x19, 0x56 }),
CAT1_BRT_CINE(1, "BRTCINE", new byte[] { 0x00, 0x06 }, new byte[] { 0x19, 0x59 }),
CAT1_BRT_TV(1, "BRTTV", new byte[] { 0x00, 0x07 }, new byte[] { 0x19, 0x51 }),
CAT1_USER(1, "User", new byte[] { 0x00, 0x08 }, new byte[] { 0x19, 0x54 }),
// Category 2: VW40, VW50, VW60, VW70, VW80, VW100, VW200, HW10, HW15, HW20
CAT2_DYNAMIC(2, "Dynamic", new byte[] { 0x00, 0x00 }),
CAT2_STANDARD(2, "Standard", new byte[] { 0x00, 0x01 }),
CAT2_CINEMA(2, "Cinema", new byte[] { 0x00, 0x02 }),
CAT2_USER1(2, "User1", new byte[] { 0x00, 0x03 }),
CAT2_USER2(2, "User2", new byte[] { 0x00, 0x04 }),
CAT2_USER3(2, "User3", new byte[] { 0x00, 0x05 }),
CAT2_DYNAMIC(2, "Dynamic", new byte[] { 0x00, 0x00 }, new byte[] { 0x19, 0x51 }),
CAT2_STANDARD(2, "Standard", new byte[] { 0x00, 0x01 }, new byte[] { 0x19, 0x52 }),
CAT2_CINEMA(2, "Cinema", new byte[] { 0x00, 0x02 }, new byte[] { 0x19, 0x53 }),
CAT2_USER1(2, "User1", new byte[] { 0x00, 0x03 }, new byte[] { 0x19, 0x54 }),
CAT2_USER2(2, "User2", new byte[] { 0x00, 0x04 }, new byte[] { 0x19, 0x55 }),
CAT2_USER3(2, "User3", new byte[] { 0x00, 0x05 }, new byte[] { 0x19, 0x56 }),
// Category 3: VW85, VW90
CAT3_DYNAMIC(3, "Dynamic", new byte[] { 0x00, 0x00 }),
CAT3_STANDARD(3, "Standard", new byte[] { 0x00, 0x01 }),
CAT3_CINEMA1(3, "Cinema1", new byte[] { 0x00, 0x02 }),
CAT3_CINEMA2(3, "Cinema2", new byte[] { 0x00, 0x03 }),
CAT3_CINEMA3(3, "Cinema3", new byte[] { 0x00, 0x04 }),
CAT3_USER(3, "User", new byte[] { 0x00, 0x05 }),
CAT3_DYNAMIC(3, "Dynamic", new byte[] { 0x00, 0x00 }, new byte[] { 0x19, 0x51 }),
CAT3_STANDARD(3, "Standard", new byte[] { 0x00, 0x01 }, new byte[] { 0x19, 0x52 }),
CAT3_CINEMA1(3, "Cinema1", new byte[] { 0x00, 0x02 }, new byte[] { 0x19, 0x53 }),
CAT3_CINEMA2(3, "Cinema2", new byte[] { 0x00, 0x03 }, new byte[] { 0x19, 0x54 }),
CAT3_CINEMA3(3, "Cinema3", new byte[] { 0x00, 0x04 }, new byte[] { 0x19, 0x55 }),
CAT3_USER(3, "User", new byte[] { 0x00, 0x05 }, new byte[] { 0x19, 0x56 }),
// Category 4: VW95, HW30ES
CAT4_DYNAMIC(4, "Dynamic", new byte[] { 0x00, 0x00 }),
CAT4_STANDARD(4, "Standard", new byte[] { 0x00, 0x01 }),
CAT4_CINEMA1(4, "Cinema1", new byte[] { 0x00, 0x02 }),
CAT4_CINEMA2(4, "Cinema2", new byte[] { 0x00, 0x03 }),
CAT4_CINEMA3(4, "Cinema3", new byte[] { 0x00, 0x04 }),
CAT4_GAME(4, "Game", new byte[] { 0x00, 0x05 }),
CAT4_PHOTO(4, "Photo", new byte[] { 0x00, 0x06 }),
CAT4_USER1(4, "User1", new byte[] { 0x00, 0x07 }),
CAT4_USER2(4, "User2", new byte[] { 0x00, 0x08 }),
CAT4_DYNAMIC(4, "Dynamic", new byte[] { 0x00, 0x00 }, new byte[] { 0x19, 0x51 }),
CAT4_STANDARD(4, "Standard", new byte[] { 0x00, 0x01 }, new byte[] { 0x19, 0x52 }),
CAT4_CINEMA1(4, "Cinema1", new byte[] { 0x00, 0x02 }, new byte[] { 0x19, 0x53 }),
CAT4_CINEMA2(4, "Cinema2", new byte[] { 0x00, 0x03 }, new byte[] { 0x19, 0x54 }),
CAT4_CINEMA3(4, "Cinema3", new byte[] { 0x00, 0x04 }, new byte[] { 0x19, 0x55 }),
CAT4_GAME(4, "Game", new byte[] { 0x00, 0x05 }, new byte[] { 0x19, 0x56 }),
CAT4_PHOTO(4, "Photo", new byte[] { 0x00, 0x06 }, new byte[] { 0x19, 0x57 }),
CAT4_USER1(4, "User1", new byte[] { 0x00, 0x07 }, new byte[] { 0x19, 0x58 }),
CAT4_USER2(4, "User2", new byte[] { 0x00, 0x08 }, new byte[] { 0x19, 0x59 }),
// Category 5: VW1000ES, VW1100ES
CAT5_CINEMA_FILM1(5, "Film1", new byte[] { 0x00, 0x00 }),
CAT5_CINEMA_FILM2(5, "Film2", new byte[] { 0x00, 0x01 }),
CAT5_CINEMA_DIGITAL(5, "Digital", new byte[] { 0x00, 0x02 }),
CAT5_REFERENCE(5, "Reference", new byte[] { 0x00, 0x03 }),
CAT5_TV(5, "TV", new byte[] { 0x00, 0x04 }),
CAT5_PHOTO(5, "Photo", new byte[] { 0x00, 0x05 }),
CAT5_GAME(5, "Game", new byte[] { 0x00, 0x06 }),
CAT5_BRT_CINE(5, "BRTCINE", new byte[] { 0x00, 0x07 }),
CAT5_BRT_TV(5, "BRTTV", new byte[] { 0x00, 0x08 });
CAT5_CINEMA_FILM1(5, "Film1", new byte[] { 0x00, 0x00 }, new byte[] { 0x19, 0x53 }),
CAT5_CINEMA_FILM2(5, "Film2", new byte[] { 0x00, 0x01 }, new byte[] { 0x19, 0x58 }),
CAT5_CINEMA_DIGITAL(5, "Digital", new byte[] { 0x00, 0x02 }, new byte[] { 0x19, 0x54 }),
CAT5_REFERENCE(5, "Reference", new byte[] { 0x00, 0x03 }, new byte[] { 0x19, 0x55 }),
CAT5_TV(5, "TV", new byte[] { 0x00, 0x04 }, new byte[] { 0x19, 0x52 }),
CAT5_PHOTO(5, "Photo", new byte[] { 0x00, 0x05 }, new byte[] { 0x19, 0x57 }),
CAT5_GAME(5, "Game", new byte[] { 0x00, 0x06 }, new byte[] { 0x19, 0x56 }),
CAT5_BRT_CINE(5, "BRTCINE", new byte[] { 0x00, 0x07 }, new byte[] { 0x19, 0x59 }),
CAT5_BRT_TV(5, "BRTTV", new byte[] { 0x00, 0x08 }, new byte[] { 0x19, 0x51 });
private int category;
private String name;
private byte[] dataCode;
private byte[] irCode;
/**
* Constructor
@ -91,11 +93,13 @@ public enum SonyProjectorCalibrationPreset {
* @param category a category of projector models for which the calibration preset is available
* @param name the name of the calibration preset
* @param dataCode the data code identifying the calibration preset
* @param irCode the IR code for the calibration preset
*/
private SonyProjectorCalibrationPreset(int category, String name, byte[] dataCode) {
private SonyProjectorCalibrationPreset(int category, String name, byte[] dataCode, byte[] irCode) {
this.category = category;
this.name = name;
this.dataCode = dataCode;
this.irCode = irCode;
}
/**
@ -116,6 +120,15 @@ public enum SonyProjectorCalibrationPreset {
return dataCode;
}
/**
* Get the IR code for the current calibration preset
*
* @return the IR code
*/
public byte[] getIrCode() {
return irCode;
}
/**
* Get the name of the current calibration preset
*
@ -144,6 +157,26 @@ public enum SonyProjectorCalibrationPreset {
return options;
}
/**
* Get the list of {@link CommandOption} associated to the available calibration presets for a particular category
* of projector models
*
* @param category a category of projector models
*
* @return the list of {@link CommandOption} associated to the available calibration presets for a provided category
* of projector models
*/
public static List<CommandOption> getCommandOptions(int category) {
List<CommandOption> options = new ArrayList<>();
for (SonyProjectorCalibrationPreset value : SonyProjectorCalibrationPreset.values()) {
if (value.getCategory() == category) {
options.add(new CommandOption("PRESET_" + value.getName().toUpperCase(),
"@text/channel-type.sonyprojector.calibrationpreset.state.option." + value.getName()));
}
}
return options;
}
/**
* Get the calibration preset associated to a name for a particular category of projector models
*
@ -157,7 +190,7 @@ public enum SonyProjectorCalibrationPreset {
*/
public static SonyProjectorCalibrationPreset getFromName(int category, String name) throws SonyProjectorException {
for (SonyProjectorCalibrationPreset value : SonyProjectorCalibrationPreset.values()) {
if (value.getCategory() == category && value.getName().equals(name)) {
if (value.getCategory() == category && value.getName().equalsIgnoreCase(name)) {
return value;
}
}

View File

@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory;
* @author Markus Wehrle - Initial contribution
* @author Laurent Garnier - Refactoring to include new channels, consider serial connection and protocol depending on
* model
* @author Laurent Garnier - Allow sending any IR command
*/
@NonNullByDefault
public abstract class SonyProjectorConnector {
@ -113,9 +114,9 @@ public abstract class SonyProjectorConnector {
setSetting(SonyProjectorItem.POWER, POWER_ON);
} else {
logger.debug("Set Power ON using IR Power command");
sendIR(SonyProjectorItem.IR_POWER_ON);
sendIR(SonyProjectorItem.POWER_ON);
if (status == null) {
sendIR(SonyProjectorItem.IR_POWER_ON);
sendIR(SonyProjectorItem.POWER_ON);
}
}
}
@ -139,7 +140,7 @@ public abstract class SonyProjectorConnector {
setSetting(SonyProjectorItem.POWER, POWER_OFF);
} else {
logger.debug("Set Power OFF using IR Power command");
sendIR(SonyProjectorItem.IR_POWER_OFF);
sendIR(SonyProjectorItem.POWER_OFF);
}
}
@ -162,7 +163,7 @@ public abstract class SonyProjectorConnector {
* @throws SonyProjectorException in case of any problem
*/
public void setCalibrationPreset(String value) throws SonyProjectorException {
setSetting(SonyProjectorItem.CALIBRATION_PRESET, model.getCalibrPresetDataCodeFromName(value));
setSetting(SonyProjectorItem.CALIBRATION_PRESET, model.getCalibrPresetFromName(value).getDataCode());
}
/**
@ -184,7 +185,7 @@ public abstract class SonyProjectorConnector {
* @throws SonyProjectorException in case of any problem
*/
public void setInput(String value) throws SonyProjectorException {
setSetting(SonyProjectorItem.INPUT, model.getInputDataCodeFromName(value));
setSetting(SonyProjectorItem.INPUT, model.getInputFromName(value).getDataCode());
}
/**
@ -509,7 +510,7 @@ public abstract class SonyProjectorConnector {
* @throws SonyProjectorException in case of any problem
*/
public void setAspect(String value) throws SonyProjectorException {
setSetting(SonyProjectorItem.ASPECT, model.getAspectCodeFromName(value));
setSetting(SonyProjectorItem.ASPECT, model.getAspectFromName(value).getDataCode());
}
/**
@ -881,6 +882,64 @@ public abstract class SonyProjectorConnector {
setSetting(SonyProjectorItem.XVCOLOR, XVCOLOR_OFF);
}
/**
* Send an IR command to the projector
*
* @param command the IR command
*
* @throws SonyProjectorException in case this IR command is not available or any other problem
*/
public void sendIrCommand(String command) throws SonyProjectorException {
byte @Nullable [] irCode = null;
boolean found = true;
if (command.startsWith("INPUT_")) {
try {
irCode = model.getInputFromName(command.substring(6)).getIrCode();
} catch (SonyProjectorException e) {
found = false;
}
} else if (command.startsWith("PRESET_")) {
try {
irCode = model.getCalibrPresetFromName(command.substring(7)).getIrCode();
} catch (SonyProjectorException e) {
found = false;
}
} else if (command.startsWith("ASPECT_")) {
try {
irCode = model.getAspectFromName(command.substring(7)).getIrCode();
} catch (SonyProjectorException e) {
found = false;
}
} else {
try {
irCode = SonyProjectorItem.getFromValue(command).getIrCode();
} catch (SonyProjectorException e) {
found = false;
}
}
if (!found) {
// Check if the command is a direct IR code in hexadecimal
// Must be 4 characters starting by either 17 or 19 or 1B
String cmd = command.trim();
if (cmd.length() != 4) {
throw new SonyProjectorException("Invalid IR code: " + command);
}
int hex;
try {
hex = Integer.parseInt(cmd, 16);
} catch (NumberFormatException e) {
throw new SonyProjectorException("Invalid IR code: " + command, e);
}
irCode = new byte[2];
irCode[0] = (byte) ((hex >> 8) & 0x000000FF);
irCode[1] = (byte) (hex & 0x000000FF);
}
if (irCode == null || !SonyProjectorItem.isValidIrCode(irCode)) {
throw new SonyProjectorException("Invalid IR code: " + command);
}
sendIR(irCode);
}
/**
* Request the projector to get the current value for a setting
*
@ -899,7 +958,7 @@ public abstract class SonyProjectorConnector {
logger.debug("Get setting {} succeeded: result data: {}", item.getName(), HexUtils.bytesToHex(result));
return result;
} catch (CommunicationException e) {
} catch (CommunicationException | SonyProjectorException e) {
throw new SonyProjectorException("Get setting " + item.getName() + " failed", e);
}
}
@ -917,7 +976,7 @@ public abstract class SonyProjectorConnector {
try {
executeCommand(item, false, data);
} catch (CommunicationException e) {
} catch (CommunicationException | SonyProjectorException e) {
throw new SonyProjectorException("Set setting " + item.getName() + " failed", e);
}
@ -931,8 +990,24 @@ public abstract class SonyProjectorConnector {
*
* @throws SonyProjectorException in case of any problem
*/
private synchronized void sendIR(SonyProjectorItem item) throws SonyProjectorException {
logger.debug("Send IR {}", item.getName());
private void sendIR(SonyProjectorItem item) throws SonyProjectorException {
byte @Nullable [] irCode = item.getIrCode();
if (irCode == null || !SonyProjectorItem.isValidIrCode(irCode)) {
throw new SonyProjectorException("Send IR code failed, code is invalid");
}
sendIR(irCode);
}
/**
* Send an IR command to the projector
*
* @param irCode the IR code (2 bytes) to send
*
* @throws SonyProjectorException in case of any problem
*/
private synchronized void sendIR(byte[] irCode) throws SonyProjectorException {
String codeStr = String.format("%02x%02x", irCode[0], irCode[1]);
logger.debug("Send IR code {}", codeStr);
try {
boolean runningSession = connected;
@ -940,7 +1015,7 @@ public abstract class SonyProjectorConnector {
open();
// Build the message and send it
writeCommand(buildMessage(item, false, DUMMY_DATA));
writeCommand(buildMessage(irCode, false, DUMMY_DATA));
// Wait at least 45 ms
Thread.sleep(45);
@ -951,13 +1026,13 @@ public abstract class SonyProjectorConnector {
close();
}
} catch (CommunicationException e) {
throw new SonyProjectorException("Send IR " + item.getName() + " failed", e);
throw new SonyProjectorException("Send IR code " + codeStr + " failed", e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new SonyProjectorException("Send IR " + item.getName() + " interrupted", e);
throw new SonyProjectorException("Send IR code " + codeStr + " interrupted", e);
}
logger.debug("Send IR {} succeeded", item.getName());
logger.debug("Send IR code {} succeeded", codeStr);
}
/**
@ -971,15 +1046,21 @@ public abstract class SonyProjectorConnector {
*
* @throws ConnectionException in case of any connection problem
* @throws CommunicationException in case of any communication problem
* @throws SonyProjectorException in case of any other problem
*/
private synchronized byte[] executeCommand(SonyProjectorItem item, boolean getCommand, byte[] data)
throws ConnectionException, CommunicationException {
throws ConnectionException, CommunicationException, SonyProjectorException {
byte @Nullable [] code = item.getCode();
if (code == null) {
throw new SonyProjectorException("Undefined data code");
}
boolean runningSession = connected;
open();
// Build the message and send it
writeCommand(buildMessage(item, getCommand, data));
writeCommand(buildMessage(code, getCommand, data));
// Read the response
byte[] responseMessage = readResponse();
@ -1029,13 +1110,13 @@ public abstract class SonyProjectorConnector {
/**
* Build the message buffer corresponding to the request of a particular information
*
* @param item the projector setting to get or set
* @param itemCode the code (2 bytes) of the projector setting to get or set
* @param getCommand true for a GET command or false for a SET command
* @param data the value to be considered in case of a SET command
*
* @return the message buffer
*/
protected abstract byte[] buildMessage(SonyProjectorItem item, boolean getCommand, byte[] data);
protected abstract byte[] buildMessage(byte[] itemCode, boolean getCommand, byte[] data);
/**
* Reads some number of bytes from the input stream and stores them into the buffer array b. The number of bytes

View File

@ -18,6 +18,7 @@ import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.sonyprojector.internal.SonyProjectorException;
import org.openhab.core.types.CommandOption;
import org.openhab.core.types.StateOption;
import org.openhab.core.util.HexUtils;
@ -31,41 +32,42 @@ public enum SonyProjectorInput {
// Category 1: VW260, VW270, VW285, VW295, VW300, VW315, VW320, VW328, VW350, VW365, VW385, VW500, VW515, VW520,
// VW528, VW550, VW570, VW600, VW665, VW675, VW695, VW760, VW870, VW885, VW995, HW45ES, HW60, HW65, HW68
CAT1_HDMI1(1, "HDMI1", new byte[] { 0x00, 0x02 }),
CAT1_HDMI2(1, "HDMI2", new byte[] { 0x00, 0x03 }),
CAT1_HDMI1(1, "HDMI1", new byte[] { 0x00, 0x02 }, new byte[] { 0x17, 0x2B }),
CAT1_HDMI2(1, "HDMI2", new byte[] { 0x00, 0x03 }, new byte[] { 0x17, 0x2C }),
// Category 2: VW40, VW50, VW60, VW70, VW80, VW85, VW200, HW10, HW15, HW20
CAT2_VIDEO(2, "Video", new byte[] { 0x00, 0x00 }),
CAT2_SVIDEO(2, "SVideo", new byte[] { 0x00, 0x01 }),
CAT2_INPUT_A(2, "InputA", new byte[] { 0x00, 0x02 }),
CAT2_COMPONENT(2, "Component", new byte[] { 0x00, 0x03 }),
CAT2_HDMI1(2, "HDMI1", new byte[] { 0x00, 0x04 }),
CAT2_HDMI2(2, "HDMI2", new byte[] { 0x00, 0x05 }),
CAT2_VIDEO(2, "Video", new byte[] { 0x00, 0x00 }, new byte[] { 0x17, 0x2A }),
CAT2_SVIDEO(2, "SVideo", new byte[] { 0x00, 0x01 }, new byte[] { 0x17, 0x5F }),
CAT2_INPUT_A(2, "InputA", new byte[] { 0x00, 0x02 }, new byte[] { 0x17, 0x2B }),
CAT2_COMPONENT(2, "Component", new byte[] { 0x00, 0x03 }, new byte[] { 0x17, 0x2C }),
CAT2_HDMI1(2, "HDMI1", new byte[] { 0x00, 0x04 }, new byte[] { 0x17, 0x6F }),
CAT2_HDMI2(2, "HDMI2", new byte[] { 0x00, 0x05 }, new byte[] { 0x17, 0x70 }),
// Category 3: VW95, VW1000ES, VW1100ES, HW30ES, HW40ES, HW50ES, HW55ES, HW58ES
CAT3_INPUT_A(3, "InputA", new byte[] { 0x00, 0x02 }),
CAT3_COMPONENT(3, "Component", new byte[] { 0x00, 0x03 }),
CAT3_HDMI1(3, "HDMI1", new byte[] { 0x00, 0x04 }),
CAT3_HDMI2(3, "HDMI2", new byte[] { 0x00, 0x05 }),
CAT3_INPUT_A(3, "InputA", new byte[] { 0x00, 0x02 }, new byte[] { 0x17, 0x2B }),
CAT3_COMPONENT(3, "Component", new byte[] { 0x00, 0x03 }, new byte[] { 0x17, 0x2C }),
CAT3_HDMI1(3, "HDMI1", new byte[] { 0x00, 0x04 }, new byte[] { 0x17, 0x6F }),
CAT3_HDMI2(3, "HDMI2", new byte[] { 0x00, 0x05 }, new byte[] { 0x17, 0x70 }),
// Category 4: VW100
CAT4_VIDEO(4, "Video", new byte[] { 0x00, 0x00 }),
CAT4_SVIDEO(4, "SVideo", new byte[] { 0x00, 0x01 }),
CAT4_INPUT_A(4, "InputA", new byte[] { 0x00, 0x02 }),
CAT4_COMPONENT(4, "Component", new byte[] { 0x00, 0x03 }),
CAT4_HDMI(4, "HDMI", new byte[] { 0x00, 0x04 }),
CAT4_DVI(4, "DVI", new byte[] { 0x00, 0x05 }),
CAT4_VIDEO(4, "Video", new byte[] { 0x00, 0x00 }, new byte[] { 0x17, 0x2A }),
CAT4_SVIDEO(4, "SVideo", new byte[] { 0x00, 0x01 }, new byte[] { 0x17, 0x5F }),
CAT4_INPUT_A(4, "InputA", new byte[] { 0x00, 0x02 }, new byte[] { 0x17, 0x2B }),
CAT4_COMPONENT(4, "Component", new byte[] { 0x00, 0x03 }, new byte[] { 0x17, 0x2C }),
CAT4_HDMI(4, "HDMI", new byte[] { 0x00, 0x04 }, new byte[] { 0x17, 0x6F }),
CAT4_DVI(4, "DVI", new byte[] { 0x00, 0x05 }, new byte[] { 0x17, 0x70 }),
// Category 5: VW90
CAT5_VIDEO(5, "Video", new byte[] { 0x00, 0x00 }),
CAT5_INPUT_A(5, "InputA", new byte[] { 0x00, 0x02 }),
CAT5_COMPONENT(5, "Component", new byte[] { 0x00, 0x03 }),
CAT5_HDMI1(5, "HDMI1", new byte[] { 0x00, 0x04 }),
CAT5_HDMI2(5, "HDMI2", new byte[] { 0x00, 0x05 });
CAT5_VIDEO(5, "Video", new byte[] { 0x00, 0x00 }, new byte[] { 0x17, 0x2A }),
CAT5_INPUT_A(5, "InputA", new byte[] { 0x00, 0x02 }, new byte[] { 0x17, 0x2B }),
CAT5_COMPONENT(5, "Component", new byte[] { 0x00, 0x03 }, new byte[] { 0x17, 0x2C }),
CAT5_HDMI1(5, "HDMI1", new byte[] { 0x00, 0x04 }, new byte[] { 0x17, 0x6F }),
CAT5_HDMI2(5, "HDMI2", new byte[] { 0x00, 0x05 }, new byte[] { 0x17, 0x70 });
private int category;
private String name;
private byte[] dataCode;
private byte[] irCode;
/**
* Constructor
@ -73,11 +75,13 @@ public enum SonyProjectorInput {
* @param category a category of projector models for which the video input is available
* @param name the name of the video input
* @param dataCode the data code identifying the video input
* @param irCode the IR code for the video input
*/
private SonyProjectorInput(int category, String name, byte[] dataCode) {
private SonyProjectorInput(int category, String name, byte[] dataCode, byte[] irCode) {
this.category = category;
this.name = name;
this.dataCode = dataCode;
this.irCode = irCode;
}
/**
@ -98,6 +102,15 @@ public enum SonyProjectorInput {
return dataCode;
}
/**
* Get the IR code for the current video input
*
* @return the IR code
*/
public byte[] getIrCode() {
return irCode;
}
/**
* Get the name of the current video input
*
@ -126,6 +139,26 @@ public enum SonyProjectorInput {
return options;
}
/**
* Get the list of {@link CommandOption} associated to the available video inputs for a particular category of
* projector models
*
* @param category a category of projector models
*
* @return the list of {@link CommandOption} associated to the available video inputs for a provided category of
* projector models
*/
public static List<CommandOption> getCommandOptions(int category) {
List<CommandOption> options = new ArrayList<>();
for (SonyProjectorInput value : SonyProjectorInput.values()) {
if (value.getCategory() == category) {
options.add(new CommandOption("INPUT_" + value.getName().toUpperCase(),
"@text/channel-type.sonyprojector.input.state.option." + value.getName()));
}
}
return options;
}
/**
* Get the video input associated to a name for a particular category of projector models
*
@ -138,7 +171,7 @@ public enum SonyProjectorInput {
*/
public static SonyProjectorInput getFromName(int category, String name) throws SonyProjectorException {
for (SonyProjectorInput value : SonyProjectorInput.values()) {
if (value.getCategory() == category && value.getName().equals(name)) {
if (value.getCategory() == category && value.getName().equalsIgnoreCase(name)) {
return value;
}
}

View File

@ -12,63 +12,81 @@
*/
package org.openhab.binding.sonyprojector.internal.communication;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.sonyprojector.internal.SonyProjectorException;
import org.openhab.core.types.CommandOption;
/**
* Represents the different kinds of commands
*
* @author Markus Wehrle - Initial contribution
* @author Laurent Garnier - Transform into an enum and rename it
* @author Laurent Garnier - Add more IR commands
*/
@NonNullByDefault
public enum SonyProjectorItem {
// Not available for VW40, VW50, VW60, VW70, VW80, VW85, VW90, VW95, VW100, VW200, VW1000ES, VW1100ES,
// HW10, HW15, HW20, HW30ES, HW35ES, HW40ES, HW50ES, HW55ES, HW58ES
POWER("Power", new byte[] { 0x01, 0x30 }),
POWER("Power On/Off", new byte[] { 0x01, 0x30 }, new byte[] { 0x17, 0x15 }),
POWER_ON("Power On", null, new byte[] { 0x17, 0x2E }),
POWER_OFF("Power Off", null, new byte[] { 0x17, 0x2F }),
INPUT("Input", new byte[] { 0x00, 0x01 }),
CALIBRATION_PRESET("Calibration Preset", new byte[] { 0x00, 0x02 }),
INPUT("Input", new byte[] { 0x00, 0x01 }, new byte[] { 0x17, 0x57 }, "input"),
CALIBRATION_PRESET("Calibration Preset", new byte[] { 0x00, 0x02 }, new byte[] { 0x19, 0x5B }, "calibrationpreset"),
CONTRAST("Contrast", new byte[] { 0x00, 0x10 }),
CONTRAST_UP("Contrast +", null, new byte[] { 0x17, 0x18 }),
CONTRAST_DOWN("Contrast -", null, new byte[] { 0x17, 0x19 }),
BRIGHTNESS("Brigtness", new byte[] { 0x00, 0x11 }),
BRIGHTNESS_UP("Brightness +", null, new byte[] { 0x17, 0x1E }),
BRIGHTNESS_DOWN("Brightness -", null, new byte[] { 0x17, 0x1F }),
COLOR("Color", new byte[] { 0x00, 0x12 }),
COLOR_UP("Color +", null, new byte[] { 0x17, 0x1A }),
COLOR_DOWN("Color -", null, new byte[] { 0x17, 0x1B }),
HUE("Hue", new byte[] { 0x00, 0x13 }),
HUE_UP("Hue +", null, new byte[] { 0x17, 0x20 }),
HUE_DOWN("Hue -", null, new byte[] { 0x17, 0x21 }),
SHARPNESS("Sharpness", new byte[] { 0x00, 0x14 }),
COLOR_TEMP("Color Temperature", new byte[] { 0x00, 0x17 }),
SHARPNESS_UP("Sharpness +", null, new byte[] { 0x17, 0x22 }),
SHARPNESS_DOWN("Sharpness -", null, new byte[] { 0x17, 0x23 }),
CONTRAST_ENHANCER("Contrast Enhancer", new byte[] { 0x00, 0x1C }, new byte[] { 0x17, 0x07 }, "contrastenhancer"),
COLOR_TEMP("Color Temperature", new byte[] { 0x00, 0x17 }, new byte[] { 0x19, 0x5C }, "colortemperature"),
GAMMA_CORRECTION("Gamma Correction", new byte[] { 0x00, 0x22 }, new byte[] { 0x19, 0x5E }, "gammacorrection"),
COLOR_SPACE("Color Space", new byte[] { 0x00, 0x3B }, new byte[] { 0x19, 0x4B }, "colorspace"),
PICTURE_MUTING("Picture Muting", new byte[] { 0x00, 0x30 }, new byte[] { 0x17, 0x24 }, "picturemuting"),
NR("NR", new byte[] { 0x00, 0x25 }),
// Not available for VW100, VW200
LAMP_CONTROL("Lamp Control", new byte[] { 0x00, 0x1A }),
CONTRAST_ENHANCER("Contrast Enhancer", new byte[] { 0x00, 0x1C }),
// Not available for VW260, VW270, VW285, VW295, VW300, VW315, VW320, VW328, VW350, VW365, HW35ES, HW40ES, HW45ES,
// HW58ES
IRIS_MODE("Iris Mode", new byte[] { 0x00, 0x1D }),
// Not available for VW315, VW320, VW328, VW365, VW515, VW520, VW528, VW665, HW60, HW65, HW68
REAL_COLOR("Real Color Processing", new byte[] { 0x00, 0x1E }),
REAL_COLOR("Real Color Processing", new byte[] { 0x00, 0x1E }, new byte[] { 0x19, 0x08 }),
// Not available for VW40, VW50, VW60, VW70, VW85, VW95, VW100, HW15, HW20, HW30ES
REALITY_CREATION("Reality Creation", new byte[] { 0x00, 0x67 }, new byte[] { 0x19, 0x4C }),
// Not available for VW40, VW50, VW60
FILM_MODE("Film Mode", new byte[] { 0x00, 0x1F }),
ASPECT("Aspect", new byte[] { 0x00, 0x20 }),
GAMMA_CORRECTION("Gamma Correction", new byte[] { 0x00, 0x22 }),
COLOR_SPACE("Color Space", new byte[] { 0x00, 0x3B }),
PICTURE_MUTING("Picture Muting", new byte[] { 0x00, 0x30 }),
NR("NR", new byte[] { 0x00, 0x25 }),
// Not available for VW40, VW50, VW60, VW70, VW100, VW260, VW270, VW285, VW295, VW300, VW315, VW320, VW328, VW350,
// VW365, VW385, VW500, VW515, VW520, VW528, VW570, VW600, VW665, VW675, VW695, VW760, VW870, VW885, VW995, HW10,
// HW15, HW20, HW30ES, HW45ES, HW60, HW65, HW68
FILM_PROJECTION("Film Projection", new byte[] { 0x00, 0x58 }, new byte[] { 0x17, 0x08 }, "filmprojection"),
// Not available for VW40, VW50, VW60, VW100, VW200, VW260, VW270, VW285, VW295, VW300, VW315, VW320, VW328, VW350,
// VW365, VW385, VW500, VW515, VW520, VW528, VW550, VW570, VW600, VW665, VW675, VW760, VW870, VW885, VW995,
// VW1000ES, VW1100ES, HW35ES, HW40ES, HW45ES, HW50ES, HW55ES, HW58ES, HW60, HW65, HW68
BLOCK_NR("Block NR", new byte[] { 0x00, 0x26 }),
MOSQUITO_NR("Mosquito NR", new byte[] { 0x00, 0x27 }),
// Not available for VW40, VW50, VW60, VW70, VW100, HW10, HW15, HW20, HW30ES
MOTION_ENHANCER("Motion Enhancer", new byte[] { 0x00, 0x59 }, new byte[] { 0x17, 0x05 }, "motionenhancer"),
// Not available for VW40, VW50, VW60, VW70, VW80, VW85, VW90, VW95, VW100, VW200, HW10, HW15, HW20, HW30ES
MPEG_NR("MPEG NR", new byte[] { 0x00, 0x6C }),
// Not available for VW40, VW50, VW60, VW100
XVCOLOR("xvColor", new byte[] { 0x00, 0x5A }),
// Not available for VW260, VW270, VW285, VW295, VW300, VW315, VW320, VW328, VW350, VW365, VW385, VW500, VW515,
// VW520, VW528, VW550, VW570, VW600, VW665, VW675, VW760, VW870, VW885, VW995, HW45ES, HW60, HW65, HW68
OVERSCAN("Overscan", new byte[] { 0x00, 0x23 }),
// Not available for VW260, VW270, VW285, VW295, VW300, VW315, VW320, VW328, VW350, VW365, HW35ES, HW40ES, HW45ES,
// HW58ES
IRIS_MODE("Iris Mode", new byte[] { 0x00, 0x1D }, new byte[] { 0x19, 0x5F }, "irismode"),
// Not available for VW100, VW260, VW270, VW285, VW295, VW300, VW315, VW320, VW328, VW350, VW365, VW385, VW500,
// VW515, VW520, VW528, VW550, VW570, VW600, VW665, VW675, VW760, VW870, VW885, VW995, VW1000ES, VW1100ES, HW35ES,
@ -79,28 +97,35 @@ public enum SonyProjectorItem {
// VW885, VW995, HW35ES, HW40ES, HW45ES, HW58ES
IRIS_MANUAL("Iris Manual", new byte[] { 0x00, 0x57 }),
// Not available for VW40, VW50, VW60, VW70, VW100, VW260, VW270, VW285, VW295, VW300, VW315, VW320, VW328, VW350,
// VW365, VW385, VW500, VW515, VW520, VW528, VW570, VW600, VW665, VW675, VW695, VW760, VW870, VW885, VW995, HW10,
// HW15, HW20, HW30ES, HW45ES, HW60, HW65, HW68
FILM_PROJECTION("Film Projection", new byte[] { 0x00, 0x58 }),
// Not available for VW40, VW50, VW60, VW100, VW200, VW260, VW270, VW285, VW295, VW300, VW315, VW320, VW328, VW350,
// VW365, VW385, VW500, VW515, VW520, VW528, VW550, VW570, VW600, VW665, VW675, VW760, VW870, VW885, VW995,
// VW1000ES, VW1100ES, HW35ES, HW40ES, HW45ES, HW50ES, HW55ES, HW58ES, HW60, HW65, HW68
BLOCK_NR("Block NR", new byte[] { 0x00, 0x26 }),
MOSQUITO_NR("Mosquito NR", new byte[] { 0x00, 0x27 }),
// Not available for VW40, VW50, VW60, VW70, VW100, HW10, HW15, HW20, HW30ES
MOTION_ENHANCER("Motion Enhancer", new byte[] { 0x00, 0x59 }),
// Not available for VW40, VW50, VW60, VW70, VW80, VW85, VW90, VW95, VW100, VW200, HW10, HW15, HW20, HW30ES
MPEG_NR("MPEG NR", new byte[] { 0x00, 0x6C }),
// Not available for VW40, VW50, VW60, VW100
XVCOLOR("xvColor", new byte[] { 0x00, 0x5A }),
// Not available for VW40, VW50, VW60, VW70, VW85, VW95, VW100, VW315, VW320, VW328, VW365, VW1000ES, VW1100ES
// HW15, HW20, HW30ES, HW35ES, HW40ES, HW50ES, HW55ES, HW58ES, HW60, HW65, HW68
HDR("HDR", new byte[] { 0x00, 0x7C }),
ASPECT("Aspect", new byte[] { 0x00, 0x20 }, new byte[] { 0x19, 0x6E }, "aspect"),
// Not available for VW260, VW270, VW285, VW295, VW300, VW315, VW320, VW328, VW350, VW365, VW385, VW500, VW515,
// VW520, VW528, VW550, VW570, VW600, VW665, VW675, VW760, VW870, VW885, VW995, HW45ES, HW60, HW65, HW68
OVERSCAN("Overscan", new byte[] { 0x00, 0x23 }),
// Not available for VW40, VW50, VW60, VW70, VW80, VW85, VW90, VW100, VW200, VW260, VW270, VW285, VW295, VW300,
// VW315, VW320, VW328, VW350, VW365, HW10, HW15, HW20, HW30ES, HW35ES, HW40ES, HW45ES, HW50ES, HW55ES, HW58ES,
// HW60, HW65, HW68
PICTURE_POSITION("Picture Position", new byte[] { 0x00, 0x66 }),
// Not available for VW40, VW50, VW60, VW70, VW85, VW95, VW100, HW15, HW20, HW30ES
REALITY_CREATION("Reality Creation", new byte[] { 0x00, 0x67 }),
// Not available for VW40, VW50, VW60, VW70, VW85, VW95, VW100, VW315, VW320, VW328, VW365, VW1000ES, VW1100ES
// HW15, HW20, HW30ES, HW35ES, HW40ES, HW50ES, HW55ES, HW58ES, HW60, HW65, HW68
HDR("HDR", new byte[] { 0x00, 0x7C }),
PICTURE_POS_185("Picture Position 1.85:1", null, new byte[] { 0x1B, 0x20 }),
PICTURE_POS_235("Picture Position 2.35:1", null, new byte[] { 0x1B, 0x21 }),
PICTURE_POS_CUSTOM1("Picture Position Custom 1", null, new byte[] { 0x1B, 0x22 }),
PICTURE_POS_CUSTOM2("Picture Position Custom 2", null, new byte[] { 0x1B, 0x23 }),
PICTURE_POS_CUSTOM3("Picture Position Custom 3", null, new byte[] { 0x1B, 0x24 }),
// Not available for VW40, VW50, VW60, VW70, VW85, VW95, VW100, VW1000ES, VW1100ES
// HW15, HW20, HW30ES, HW35ES, HW40ES, HW50ES, HW55ES, HW58ES
@ -113,36 +138,125 @@ public enum SonyProjectorItem {
// Not available for VW40, VW50, VW60, VW70, VW100
STATUS_ERROR2("Status Error 2", new byte[] { 0x01, 0x25 }),
IR_POWER_ON("Power On", new byte[] { 0x17, 0x2E }),
IR_POWER_OFF("Power Off", new byte[] { 0x17, 0x2F }),
CATEGORY_CODE("Category Code", new byte[] { (byte) 0x80, 0x00 }),
MODEL_NAME("Model Name", new byte[] { (byte) 0x80, 0x01 }),
SERIAL_NUMBER("Serial Number", new byte[] { (byte) 0x80, 0x02 }),
INSTALLATION_LOCATION("Installation Location", new byte[] { (byte) 0x80, 0x03 });
INSTALLATION_LOCATION("Installation Location", new byte[] { (byte) 0x80, 0x03 }),
MENU("Menu", null, new byte[] { 0x17, 0x29 }),
UP("Cursor UP", null, new byte[] { 0x17, 0x35 }),
DOWN("Cursor DOWN", null, new byte[] { 0x17, 0x36 }),
LEFT("Cursor LEFT", null, new byte[] { 0x17, 0x34 }),
RIGHT("Cursor RIGHT", null, new byte[] { 0x17, 0x33 }),
ENTER("Enter", null, new byte[] { 0x17, 0x5A }),
RESET("Reset", null, new byte[] { 0x17, 0x7B }),
MEMORY("Memory", null, new byte[] { 0x17, 0x5E }),
STATUS_ON("Status On", null, new byte[] { 0x17, 0x25 }),
STATUS_OFF("Status Off", null, new byte[] { 0x17, 0x26 }),
ADJUST_PICTURE("Adjust Picture", null, new byte[] { 0x19, 0x09 }),
COLOR_CORRECTION("Color Correction", null, new byte[] { 0x1B, 0x1C }),
PITCH("Screen Pitch", null, new byte[] { 0x17, 0x47 }),
SHIFT("Screen Shift", null, new byte[] { 0x17, 0x48 }),
APA("APA", null, new byte[] { 0x19, 0x60 }),
DOT_PHASE("Dot Phase", null, new byte[] { 0x19, 0x61 }),
V_KEYSTONE("V Keystone", null, new byte[] { 0x19, 0x3A }),
V_KEYSTONE_UP("V Keystone +", null, new byte[] { 0x19, 0x00 }),
V_KEYSTONE_DOWN("V Keystone -", null, new byte[] { 0x19, 0x01 }),
LENS_CONTROL("Lens Control", null, new byte[] { 0x19, 0x78 }),
LENS_SHIFT("Lens Shift", null, new byte[] { 0x19, 0x63 }),
LENS_SHIFT_LEFT("Lens Shift LEFT", null, new byte[] { 0x19, 0x02 }),
LENS_SHIFT_RIGHT("Lens Shift RIGHT", null, new byte[] { 0x19, 0x03 }),
LENS_SHIFT_UP("Lens Shift UP", null, new byte[] { 0x17, 0x72 }),
LENS_SHIFT_DOWN("Lens Shift DOWN", null, new byte[] { 0x17, 0x73 }),
LENS_ZOOM("Lens Zoom", null, new byte[] { 0x19, 0x62 }),
LENS_ZOOM_LARGE("Lens Zoom Large", null, new byte[] { 0x17, 0x77 }),
LENS_ZOOM_SMALL("Lens Zoom Small", null, new byte[] { 0x17, 0x78 }),
LENS_FOCUS("Lens Focus", null, new byte[] { 0x19, 0x64 }),
LENS_FOCUS_FAR("Lens Focus Far", null, new byte[] { 0x17, 0x74 }),
LENS_FOCUS_NEAR("Lens Focus Near", null, new byte[] { 0x17, 0x75 }),
LENS_POSITION("Lens Position", null, new byte[] { 0x1B, 0x18 }),
MODE_3D("3D", null, new byte[] { 0x19, 0x3B }),
OPTIONS("Options", null, new byte[] { 0x1B, 0x6E }),
EXIT("Exit", null, new byte[] { 0x1B, 0x6F }),
SYNC_MENU("Sync Menu", null, new byte[] { 0x1B, 0x70 }),
PLAY("Play", null, new byte[] { 0x1B, 0x71 }),
STOP("Stop", null, new byte[] { 0x1B, 0x72 }),
PAUSE("Pause", null, new byte[] { 0x1B, 0x73 }),
FAST_REWIND("Fast Rewind", null, new byte[] { 0x1B, 0x74 }),
FAST_FORWARD("Fast Forward", null, new byte[] { 0x1B, 0x75 }),
PREVIOUS("Previous", null, new byte[] { 0x1B, 0x76 }),
NEXT("Next", null, new byte[] { 0x1B, 0x77 });
private String name;
private byte[] code;
private byte @Nullable [] code;
private byte @Nullable [] irCode;
private @Nullable String channelType;
/**
*
* @param name the item name
* @param code the data code associated to the item
*/
private SonyProjectorItem(String name, byte[] code) {
private SonyProjectorItem(String name, byte @Nullable [] code) {
this(name, code, null, null);
}
/**
*
* @param name the item name
* @param code the data code associated to the item
* @param irCode the IR code associated to the item
*/
private SonyProjectorItem(String name, byte @Nullable [] code, byte @Nullable [] irCode) {
this(name, code, irCode, null);
}
/**
*
* @param name the item name
* @param code the data code associated to the item
* @param irCode the IR code associated to the item
* @param channelType the channel type id to consider to retrieve the command option label
*/
private SonyProjectorItem(String name, byte @Nullable [] code, byte @Nullable [] irCode,
@Nullable String channelType) {
this.name = name;
this.code = code;
this.irCode = irCode;
this.channelType = channelType;
}
/**
* Get the data code associated to the current item
*
* @return the data code
* @return the data code or null if undefined
*/
public byte[] getCode() {
public byte @Nullable [] getCode() {
return code;
}
/**
* Get the IR code associated to the current item
*
* @return the IR code or null if undefined
*/
public byte @Nullable [] getIrCode() {
return irCode;
}
/**
* Get the item name
*
@ -151,4 +265,66 @@ public enum SonyProjectorItem {
public String getName() {
return name;
}
/**
* Get the channel type id to consider to retrieve the command option label
*
* @return the channel type id
*/
public @Nullable String getChannelType() {
return channelType;
}
public static boolean isValidIrCode(byte @Nullable [] irCode) {
if (irCode != null && irCode.length == 2) {
return irCode[0] == 0x17 || irCode[0] == 0x19 || irCode[0] == 0x1B;
}
return false;
}
/**
* Get the command associated to a value
*
* @param val the value used to identify the command
*
* @return the command associated to the searched value
*
* @throws SonyProjectorException - If no command is associated to the searched value
*/
public static SonyProjectorItem getFromValue(String val) throws SonyProjectorException {
for (SonyProjectorItem value : SonyProjectorItem.values()) {
if (value.name().equalsIgnoreCase(val)) {
return value;
}
}
throw new SonyProjectorException("Invalid value for a command: " + val);
}
/**
* Get the list of {@link CommandOption} associated to the available IR commands
*
* @param inputOptions the command options associated to the video inputs
* @param presetOptions the command options associated to the calibration presets
* @param aspectOptions the command options associated to the aspect ratios
*
* @return the list of {@link CommandOption} associated to the available IR commands
*/
public static List<CommandOption> getIRCommandOptions(List<CommandOption> inputOptions,
List<CommandOption> presetOptions, List<CommandOption> aspectOptions) {
List<CommandOption> options = new ArrayList<>();
for (SonyProjectorItem value : SonyProjectorItem.values()) {
if (isValidIrCode(value.getIrCode())) {
options.add(new CommandOption(value.name(), value.getChannelType() == null ? value.getName()
: "@text/channel-type.sonyprojector." + value.getChannelType() + ".label"));
}
if (value == INPUT) {
options.addAll(inputOptions);
} else if (value == CALIBRATION_PRESET) {
options.addAll(presetOptions);
} else if (value == ASPECT) {
options.addAll(aspectOptions);
}
}
return options;
}
}

View File

@ -20,6 +20,7 @@ import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNullByDefault;
@ -155,7 +156,7 @@ public class SonyProjectorSdcpConnector extends SonyProjectorConnector {
}
@Override
protected byte[] buildMessage(SonyProjectorItem item, boolean getCommand, byte[] data) {
protected byte[] buildMessage(byte[] itemCode, boolean getCommand, byte[] data) {
byte[] communityData = community.getBytes();
byte[] message = new byte[10 + data.length];
message[0] = HEADER[0];
@ -165,8 +166,8 @@ public class SonyProjectorSdcpConnector extends SonyProjectorConnector {
message[4] = communityData[2];
message[5] = communityData[3];
message[6] = getCommand ? GET : SET;
message[7] = item.getCode()[0];
message[8] = item.getCode()[1];
message[7] = itemCode[0];
message[8] = itemCode[1];
message[9] = getCommand ? 0 : (byte) data.length;
if (!getCommand) {
System.arraycopy(data, 0, message, 10, data.length);
@ -259,9 +260,10 @@ public class SonyProjectorSdcpConnector extends SonyProjectorConnector {
// Item number should be the same as used for sending
byte[] itemResponseMsg = Arrays.copyOfRange(responseMessage, 7, 9);
if (!Arrays.equals(itemResponseMsg, item.getCode())) {
byte[] itemSentMsg = Objects.requireNonNull(item.getCode());
if (!Arrays.equals(itemResponseMsg, itemSentMsg)) {
logger.debug("Unexpected item number in response: {} rather than {}", HexUtils.bytesToHex(itemResponseMsg),
HexUtils.bytesToHex(item.getCode()));
HexUtils.bytesToHex(itemSentMsg));
throw new CommunicationException("Unexpected item number in response");
}

View File

@ -14,7 +14,6 @@ package org.openhab.binding.sonyprojector.internal.communication.sdcp;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.sonyprojector.internal.SonyProjectorModel;
import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorItem;
import org.openhab.core.i18n.CommunicationException;
import org.openhab.core.i18n.ConnectionException;
import org.openhab.core.util.HexUtils;
@ -33,7 +32,7 @@ public class SonyProjectorSdcpSimuConnector extends SonyProjectorSdcpConnector {
private final Logger logger = LoggerFactory.getLogger(SonyProjectorSdcpSimuConnector.class);
private SonyProjectorItem lastItem = SonyProjectorItem.POWER;
private byte[] lastItemCode = new byte[] { 0x00, 0x00 };
/**
* Constructor
@ -61,9 +60,9 @@ public class SonyProjectorSdcpSimuConnector extends SonyProjectorSdcpConnector {
}
@Override
protected byte[] buildMessage(SonyProjectorItem item, boolean getCommand, byte[] data) {
lastItem = item;
return super.buildMessage(item, getCommand, data);
protected byte[] buildMessage(byte[] itemCode, boolean getCommand, byte[] data) {
lastItemCode = itemCode;
return super.buildMessage(itemCode, getCommand, data);
}
@Override
@ -77,8 +76,8 @@ public class SonyProjectorSdcpSimuConnector extends SonyProjectorSdcpConnector {
message[4] = communityData[2];
message[5] = communityData[3];
message[6] = OK;
message[7] = lastItem.getCode()[0];
message[8] = lastItem.getCode()[1];
message[7] = lastItemCode[0];
message[8] = lastItemCode[1];
message[9] = 2;
message[10] = 0;
message[11] = 1;

View File

@ -16,6 +16,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Objects;
import java.util.TooManyListenersException;
import java.util.concurrent.TimeUnit;
@ -162,11 +163,11 @@ public class SonyProjectorSerialConnector extends SonyProjectorConnector impleme
}
@Override
protected byte[] buildMessage(SonyProjectorItem item, boolean getCommand, byte[] data) {
protected byte[] buildMessage(byte[] itemCode, boolean getCommand, byte[] data) {
byte[] message = new byte[8];
message[0] = START_CODE;
message[1] = item.getCode()[0];
message[2] = item.getCode()[1];
message[1] = itemCode[0];
message[2] = itemCode[1];
message[3] = getCommand ? GET : SET;
message[4] = data[0];
message[5] = data[1];
@ -246,9 +247,10 @@ public class SonyProjectorSerialConnector extends SonyProjectorConnector impleme
if (responseMessage[3] == TYPE_ITEM) {
// Item number should be the same as used for sending
byte[] itemResponseMsg = Arrays.copyOfRange(responseMessage, 1, 3);
if (!Arrays.equals(itemResponseMsg, item.getCode())) {
byte[] itemSentMsg = Objects.requireNonNull(item.getCode());
if (!Arrays.equals(itemResponseMsg, itemSentMsg)) {
logger.debug("Unexpected item number in response: {} rather than {}",
HexUtils.bytesToHex(itemResponseMsg), HexUtils.bytesToHex(item.getCode()));
HexUtils.bytesToHex(itemResponseMsg), HexUtils.bytesToHex(itemSentMsg));
throw new CommunicationException("Unexpected item number in response");
}
} else if (responseMessage[3] == TYPE_ACK) {

View File

@ -19,10 +19,12 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.sonyprojector.internal.SonyProjectorCommandDescriptionOptionProvider;
import org.openhab.binding.sonyprojector.internal.SonyProjectorException;
import org.openhab.binding.sonyprojector.internal.SonyProjectorModel;
import org.openhab.binding.sonyprojector.internal.SonyProjectorStateDescriptionOptionProvider;
import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorConnector;
import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorItem;
import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorStatusPower;
import org.openhab.binding.sonyprojector.internal.communication.sdcp.SonyProjectorSdcpConnector;
import org.openhab.binding.sonyprojector.internal.communication.sdcp.SonyProjectorSdcpSimuConnector;
@ -60,6 +62,7 @@ import org.slf4j.LoggerFactory;
*
* @author Markus Wehrle - Initial contribution
* @author Laurent Garnier - Refactoring, poll thread for regular channels updates, new serial thing type, new channels
* @author Laurent Garnier - Add new channel "ircommand"
*/
@NonNullByDefault
public class SonyProjectorHandler extends BaseThingHandler {
@ -70,6 +73,7 @@ public class SonyProjectorHandler extends BaseThingHandler {
private final Logger logger = LoggerFactory.getLogger(SonyProjectorHandler.class);
private final SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider;
private final SonyProjectorCommandDescriptionOptionProvider commandDescriptionProvider;
private final SerialPortManager serialPortManager;
private final TranslationProvider i18nProvider;
@ -88,9 +92,11 @@ public class SonyProjectorHandler extends BaseThingHandler {
private final Object commandLock = new Object();
public SonyProjectorHandler(Thing thing, SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider,
SonyProjectorCommandDescriptionOptionProvider commandDescriptionProvider,
SerialPortManager serialPortManager, TranslationProvider i18nProvider) {
super(thing);
this.stateDescriptionProvider = stateDescriptionProvider;
this.commandDescriptionProvider = commandDescriptionProvider;
this.serialPortManager = serialPortManager;
this.i18nProvider = i18nProvider;
this.bundle = FrameworkUtil.getBundle(this.getClass());
@ -287,6 +293,9 @@ public class SonyProjectorHandler extends BaseThingHandler {
case CHANNEL_PICTURE_POSITION:
connector.setPicturePosition(command.toString());
break;
case CHANNEL_IR_COMMAND:
connector.sendIrCommand(command.toString());
break;
default:
throw new SonyProjectorException("Unexpected command");
}
@ -521,6 +530,9 @@ public class SonyProjectorHandler extends BaseThingHandler {
model.getAspectStateOptions());
stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_PICTURE_POSITION),
model.getPicturePositionStateOptions());
commandDescriptionProvider.setCommandOptions(new ChannelUID(getThing().getUID(), CHANNEL_IR_COMMAND),
SonyProjectorItem.getIRCommandOptions(model.getInputCommandOptions(),
model.getCalibrPresetCommandOptions(), model.getAspectCommandOptions()));
}
return model;
}

View File

@ -64,6 +64,8 @@ channel-type.sonyprojector.hue.label = Hue
channel-type.sonyprojector.hue.description = Adjust the color tone
channel-type.sonyprojector.input.label = Video Input
channel-type.sonyprojector.input.description = Select the equipment from which to display images
channel-type.sonyprojector.ircommand.label = IR Command
channel-type.sonyprojector.ircommand.description = Send an infrared remote command
channel-type.sonyprojector.irismanual.label = Iris Manual
channel-type.sonyprojector.irismanual.description = Force the iris aperture to a fixed value
channel-type.sonyprojector.irismode.label = Iris Mode
@ -203,6 +205,69 @@ channel-type.sonyprojector.input.state.option.Video = Video
channel-type.sonyprojector.input.state.option.SVideo = S-Video
channel-type.sonyprojector.input.state.option.InputA = Input A
channel-type.sonyprojector.input.state.option.Component = Component
channel-type.sonyprojector.ircommand.command.option.POWER = Power On/Off
channel-type.sonyprojector.ircommand.command.option.POWER_ON = Power On
channel-type.sonyprojector.ircommand.command.option.POWER_OFF = Power Off
channel-type.sonyprojector.ircommand.command.option.CONTRAST_UP = Contrast +
channel-type.sonyprojector.ircommand.command.option.CONTRAST_DOWN = Contrast -
channel-type.sonyprojector.ircommand.command.option.BRIGHTNESS_UP = Brightness +
channel-type.sonyprojector.ircommand.command.option.BRIGHTNESS_DOWN = Brightness -
channel-type.sonyprojector.ircommand.command.option.COLOR_UP = Color +
channel-type.sonyprojector.ircommand.command.option.COLOR_DOWN = Color -
channel-type.sonyprojector.ircommand.command.option.HUE_UP = Hue +
channel-type.sonyprojector.ircommand.command.option.HUE_DOWN = Hue -
channel-type.sonyprojector.ircommand.command.option.SHARPNESS_UP = Sharpness +
channel-type.sonyprojector.ircommand.command.option.SHARPNESS_DOWN = Sharpness -
channel-type.sonyprojector.ircommand.command.option.REAL_COLOR = Real Color Processing
channel-type.sonyprojector.ircommand.command.option.REALITY_CREATION = Reality Creation
channel-type.sonyprojector.ircommand.command.option.PICTURE_POS_185 = Picture Position 1.85:1
channel-type.sonyprojector.ircommand.command.option.PICTURE_POS_235 = Picture Position 2.35:1
channel-type.sonyprojector.ircommand.command.option.PICTURE_POS_CUSTOM1 = Picture Position Custom 1
channel-type.sonyprojector.ircommand.command.option.PICTURE_POS_CUSTOM2 = Picture Position Custom 2
channel-type.sonyprojector.ircommand.command.option.PICTURE_POS_CUSTOM3 = Picture Position Custom 3
channel-type.sonyprojector.ircommand.command.option.MENU = Menu
channel-type.sonyprojector.ircommand.command.option.UP = Cursor UP
channel-type.sonyprojector.ircommand.command.option.DOWN = Cursor DOWN
channel-type.sonyprojector.ircommand.command.option.LEFT = Cursor LEFT
channel-type.sonyprojector.ircommand.command.option.RIGHT = Cursor RIGHT
channel-type.sonyprojector.ircommand.command.option.ENTER = Enter
channel-type.sonyprojector.ircommand.command.option.RESET = Reset
channel-type.sonyprojector.ircommand.command.option.MEMORY = Memory
channel-type.sonyprojector.ircommand.command.option.STATUS_ON = Status On
channel-type.sonyprojector.ircommand.command.option.STATUS_OFF = Status Off
channel-type.sonyprojector.ircommand.command.option.ADJUST_PICTURE = Adjust Picture
channel-type.sonyprojector.ircommand.command.option.COLOR_CORRECTION = Color Correction
channel-type.sonyprojector.ircommand.command.option.PITCH = Screen Pitch
channel-type.sonyprojector.ircommand.command.option.SHIFT = Screen Shift
channel-type.sonyprojector.ircommand.command.option.APA = APA
channel-type.sonyprojector.ircommand.command.option.DOT_PHASE = Dot Phase
channel-type.sonyprojector.ircommand.command.option.V_KEYSTONE = V Keystone
channel-type.sonyprojector.ircommand.command.option.V_KEYSTONE_UP = V Keystone +
channel-type.sonyprojector.ircommand.command.option.V_KEYSTONE_DOWN = V Keystone -
channel-type.sonyprojector.ircommand.command.option.LENS_CONTROL = Lens Control
channel-type.sonyprojector.ircommand.command.option.LENS_SHIFT = Lens Shift
channel-type.sonyprojector.ircommand.command.option.LENS_SHIFT_LEFT = Lens Shift LEFT
channel-type.sonyprojector.ircommand.command.option.LENS_SHIFT_RIGHT = Lens Shift RIGHT
channel-type.sonyprojector.ircommand.command.option.LENS_SHIFT_UP = Lens Shift UP
channel-type.sonyprojector.ircommand.command.option.LENS_SHIFT_DOWN = Lens Shift DOWN
channel-type.sonyprojector.ircommand.command.option.LENS_ZOOM = Lens Zoom
channel-type.sonyprojector.ircommand.command.option.LENS_ZOOM_LARGE = Lens Zoom Large
channel-type.sonyprojector.ircommand.command.option.LENS_ZOOM_SMALL = Lens Zoom Small
channel-type.sonyprojector.ircommand.command.option.LENS_FOCUS = Lens Focus
channel-type.sonyprojector.ircommand.command.option.LENS_FOCUS_FAR = Lens Focus Far
channel-type.sonyprojector.ircommand.command.option.LENS_FOCUS_NEAR = Lens Focus Near
channel-type.sonyprojector.ircommand.command.option.LENS_POSITION = Lens Position
channel-type.sonyprojector.ircommand.command.option.MODE_3D = 3D
channel-type.sonyprojector.ircommand.command.option.OPTIONS = Options
channel-type.sonyprojector.ircommand.command.option.EXIT = Exit
channel-type.sonyprojector.ircommand.command.option.SYNC_MENU = Sync Menu
channel-type.sonyprojector.ircommand.command.option.PLAY = Play
channel-type.sonyprojector.ircommand.command.option.STOP = Stop
channel-type.sonyprojector.ircommand.command.option.PAUSE = Pause
channel-type.sonyprojector.ircommand.command.option.FAST_REWIND = Fast Rewind
channel-type.sonyprojector.ircommand.command.option.FAST_FORWARD = Fast Forward
channel-type.sonyprojector.ircommand.command.option.PREVIOUS = Previous
channel-type.sonyprojector.ircommand.command.option.NEXT = Next
channel-type.sonyprojector.irismode.state.option.Full = Full
channel-type.sonyprojector.irismode.state.option.Limited = Limited
channel-type.sonyprojector.irismode.state.option.AutoFull = Auto Full

View File

@ -201,4 +201,10 @@
<state readOnly="true" pattern="%d h"></state>
</channel-type>
<channel-type id="ircommand" advanced="true">
<item-type>String</item-type>
<label>IR Command</label>
<description>Send an infrared remote command</description>
</channel-type>
</thing:thing-descriptions>

View File

@ -40,8 +40,13 @@
<channel id="overscan" typeId="overscan"/>
<channel id="pictureposition" typeId="pictureposition"/>
<channel id="lampusetime" typeId="lampusetime"/>
<channel id="ircommand" typeId="ircommand"/>
</channels>
<properties>
<property name="thingTypeVersion">1</property>
</properties>
<config-description>
<parameter name="host" type="text" required="true">
<context>network-address</context>

View File

@ -40,8 +40,13 @@
<channel id="overscan" typeId="overscan"/>
<channel id="pictureposition" typeId="pictureposition"/>
<channel id="lampusetime" typeId="lampusetime"/>
<channel id="ircommand" typeId="ircommand"/>
</channels>
<properties>
<property name="thingTypeVersion">1</property>
</properties>
<config-description>
<parameter name="port" type="text" required="true">
<context>serial-port</context>

View File

@ -40,8 +40,13 @@
<channel id="overscan" typeId="overscan"/>
<channel id="pictureposition" typeId="pictureposition"/>
<channel id="lampusetime" typeId="lampusetime"/>
<channel id="ircommand" typeId="ircommand"/>
</channels>
<properties>
<property name="thingTypeVersion">1</property>
</properties>
<config-description>
<parameter name="host" type="text" required="true">
<context>network-address</context>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
<thing-type uid="sonyprojector:ethernetconnection">
<instruction-set targetVersion="1">
<add-channel id="ircommand">
<type>sonyprojector:ircommand</type>
</add-channel>
</instruction-set>
</thing-type>
<thing-type uid="sonyprojector:serialconnection">
<instruction-set targetVersion="1">
<add-channel id="ircommand">
<type>sonyprojector:ircommand</type>
</add-channel>
</instruction-set>
</thing-type>
<thing-type uid="sonyprojector:serialoveripconnection">
<instruction-set targetVersion="1">
<add-channel id="ircommand">
<type>sonyprojector:ircommand</type>
</add-channel>
</instruction-set>
</thing-type>
</update:update-descriptions>