| 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
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";
}
--- /dev/null
+/**
+ * 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;
+ }
+}
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;
}
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;
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;
/**
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
*
*
* @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);
}
/**
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
*
*
* @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);
}
/**
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
*
*
* @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);
}
/**
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;
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
* @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;
}
/**
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
*
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
*
*/
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;
}
}
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;
// 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
* @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;
}
/**
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
*
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
*
*/
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;
}
}
* @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 {
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);
}
}
}
setSetting(SonyProjectorItem.POWER, POWER_OFF);
} else {
logger.debug("Set Power OFF using IR Power command");
- sendIR(SonyProjectorItem.IR_POWER_OFF);
+ sendIR(SonyProjectorItem.POWER_OFF);
}
}
* @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());
}
/**
* @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());
}
/**
* @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());
}
/**
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
*
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);
}
}
try {
executeCommand(item, false, data);
- } catch (CommunicationException e) {
+ } catch (CommunicationException | SonyProjectorException e) {
throw new SonyProjectorException("Set setting " + item.getName() + " failed", e);
}
*
* @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;
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);
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);
}
/**
*
* @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();
/**
* 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
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;
// 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
* @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;
}
/**
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
*
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
*
*/
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;
}
}
*/
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,
// 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
// 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 @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[] code) {
+ 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
*
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;
+ }
}
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;
}
@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];
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);
// 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");
}
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;
private final Logger logger = LoggerFactory.getLogger(SonyProjectorSdcpSimuConnector.class);
- private SonyProjectorItem lastItem = SonyProjectorItem.POWER;
+ private byte[] lastItemCode = new byte[] { 0x00, 0x00 };
/**
* Constructor
}
@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
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;
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;
}
@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];
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) {
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;
*
* @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 {
private final Logger logger = LoggerFactory.getLogger(SonyProjectorHandler.class);
private final SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider;
+ private final SonyProjectorCommandDescriptionOptionProvider commandDescriptionProvider;
private final SerialPortManager serialPortManager;
private final TranslationProvider i18nProvider;
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());
case CHANNEL_PICTURE_POSITION:
connector.setPicturePosition(command.toString());
break;
+ case CHANNEL_IR_COMMAND:
+ connector.sendIrCommand(command.toString());
+ break;
default:
throw new SonyProjectorException("Unexpected command");
}
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;
}
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
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
<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>
<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>
<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>
<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>
--- /dev/null
+<?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>