]> git.basschouten.com Git - openhab-addons.git/commitdiff
[sonyprojector] Add new channel to send infrared remote commands (#15753)
authorlolodomo <lg.hc@free.fr>
Tue, 12 Dec 2023 22:20:10 +0000 (23:20 +0100)
committerGitHub <noreply@github.com>
Tue, 12 Dec 2023 22:20:10 +0000 (23:20 +0100)
Fix #15409

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
20 files changed:
bundles/org.openhab.binding.sonyprojector/README.md
bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorBindingConstants.java
bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorCommandDescriptionOptionProvider.java [new file with mode: 0644]
bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorHandlerFactory.java
bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorModel.java
bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/SonyProjectorAspect.java
bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/SonyProjectorCalibrationPreset.java
bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/SonyProjectorConnector.java
bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/SonyProjectorInput.java
bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/SonyProjectorItem.java
bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpConnector.java
bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/sdcp/SonyProjectorSdcpSimuConnector.java
bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/communication/serial/SonyProjectorSerialConnector.java
bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/handler/SonyProjectorHandler.java
bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/i18n/sonyprojector.properties
bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/thing/channels.xml
bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/thing/ethernet.xml
bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/thing/serial.xml
bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/thing/serialoverip.xml
bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/update/instructions.xml [new file with mode: 0644]

index 40d3795597575e01747e386143b082b32e7a7902..ab473a0e9b9e87424d16c9419966ff9c64b67506 100644 (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
 
index a630f2805399fadd8dffb864c178b4406c3735b0..a6bba83570babea329275d06c41795996f0aff79 100644 (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";
 }
diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorCommandDescriptionOptionProvider.java b/bundles/org.openhab.binding.sonyprojector/src/main/java/org/openhab/binding/sonyprojector/internal/SonyProjectorCommandDescriptionOptionProvider.java
new file mode 100644 (file)
index 0000000..580c14e
--- /dev/null
@@ -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;
+    }
+}
index fd4db527f7353042ae94031e9817e1096c0e4005..e9dd645015df29e8732167a368111b6bd6d47166 100644 (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;
index 72e11135dd4a1d6a00df5a7be799e9a7caab370b..bd9fbe17f90d1441a0567a30a1d38543f1d75b1e 100644 (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);
     }
 
     /**
index 86c53fca880d442e3b2bdf0996f6a014628f0bee..465383582c8e1178da1ece50b434eeb2800796e7 100644 (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;
             }
         }
index 49a72c86d8061735d95279b7738f1df67ce77024..e9b6f268d608ce0a254fc670e99daa06643ad317 100644 (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;
             }
         }
index ccce85b9d743e027bbd89b4b5310d76804b5c7ab..542164d15098fe5430e4881eb625c425c684b87f 100644 (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
index d440af63fa3e468e616a9cbb0e1e38707f947673..267cde4cfc4cd15a6443625b54c68d2800cb7cad 100644 (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;
             }
         }
index eff4c7de3ea249719fda0531b23faedee99110e3..7b05c25add1528db68144160a437c463015bd2e4 100644 (file)
  */
 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 @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
      *
@@ -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;
+    }
 }
index 3bd2c14007fee0aff11823ede1d165381e423bb8..123f4bab515c8f93bbff23b21260bd339bb242b2 100644 (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");
         }
 
index 7888dfb188fe0a28d31d416742716d6139a3a84d..39dd1d27671e46db0b511160ad20a69d6f37851f 100644 (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;
index 1a41ac8188e1b78eadc8211162d159a2a365d97a..2b9460f50f5b1729fd8a119f3684637210e74298 100644 (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) {
index 006c2925d5c5afba7253030cdf61bfb1c04c673d..bf3765f6e88443d87b9fa3a68a0127b5d47e8804 100644 (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;
     }
index 0088049891c1a1b53531e9333ffe205d26e75222..5ad09ee8447e93249dc6cb15effecef09002cf16 100644 (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
index b3d60ceb5a9fdadac24fd3c01289cb3c159f447c..f4be79482116b29c2ef6f5d5e548462ad9487aa9 100644 (file)
                <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>
index d7043339102377deedc87fed2c16679b15002491..70f0aa5f529e7e2c1b51dfd06a4d4b93b7b372d0 100644 (file)
                        <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>
index 1352be04d3c5d718c1c8691287ccc87c65d1d8a6..ba1cd48b2c6b00bffdd263d2522ff5d0101e6a80 100644 (file)
                        <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>
index 2c382cc360bfc323c74d3d9105f96f6727e3c744..f5935bafce188742e8f916489322276800e21c3c 100644 (file)
                        <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>
diff --git a/bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/update/instructions.xml b/bundles/org.openhab.binding.sonyprojector/src/main/resources/OH-INF/update/instructions.xml
new file mode 100644 (file)
index 0000000..2d8396e
--- /dev/null
@@ -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>