2 * Copyright (c) 2010-2021 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.sonyprojector.internal.communication;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.io.OutputStream;
18 import java.util.Arrays;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.sonyprojector.internal.SonyProjectorException;
23 import org.openhab.binding.sonyprojector.internal.SonyProjectorModel;
24 import org.openhab.core.library.types.OnOffType;
25 import org.openhab.core.util.HexUtils;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * Class for communicating with Sony Projectors
32 * @author Markus Wehrle - Initial contribution
33 * @author Laurent Garnier - Refactoring to include new channels, consider serial connection and protocol depending on
37 public abstract class SonyProjectorConnector {
39 private final Logger logger = LoggerFactory.getLogger(SonyProjectorConnector.class);
41 private static final byte[] DUMMY_DATA = new byte[] { 0x00, 0x00 };
42 private static final byte[] POWER_ON = new byte[] { 0x00, 0x01 };
43 private static final byte[] POWER_OFF = new byte[] { 0x00, 0x00 };
44 private static final byte[] OVERSCAN_ON = new byte[] { 0x00, 0x01 };
45 private static final byte[] OVERSCAN_OFF = new byte[] { 0x00, 0x00 };
46 private static final byte[] PICTURE_ON = new byte[] { 0x00, 0x01 };
47 private static final byte[] PICTURE_OFF = new byte[] { 0x00, 0x00 };
48 private static final byte[] XVCOLOR_ON = new byte[] { 0x00, 0x01 };
49 private static final byte[] XVCOLOR_OFF = new byte[] { 0x00, 0x00 };
51 private SonyProjectorModel model;
53 /** The output stream */
54 protected @Nullable OutputStream dataOut;
56 /** The input stream */
57 protected @Nullable InputStream dataIn;
59 /** true if the connection is established, false if not */
60 protected boolean connected;
67 * @param model the projector model in use
68 * @param simu whether the communication is simulated or real
70 public SonyProjectorConnector(SonyProjectorModel model, boolean simu) {
76 * Set the projector model in use
78 * @param model the projector model in use
80 public void setModel(SonyProjectorModel model) {
85 * Request the projector to get the current power status
87 * @return the current power status
89 * @throws SonyProjectorException - In case of any problem
91 public SonyProjectorStatusPower getStatusPower() throws SonyProjectorException {
92 return SonyProjectorStatusPower.getFromDataCode(getSetting(SonyProjectorItem.STATUS_POWER));
96 * Power ON the projector
98 * @throws SonyProjectorException - In case the projector is not ready for a power ON command or any other problem
100 public void powerOn() throws SonyProjectorException {
101 SonyProjectorStatusPower status = null;
103 status = getStatusPower();
104 } catch (SonyProjectorException e) {
106 logger.debug("Current Power Status: {}", status == null ? "undefined" : status.getName());
107 if (status != null && status != SonyProjectorStatusPower.STANDBY) {
108 throw new SonyProjectorException("Projector not ready for command ON");
109 } else if (model.isPowerCmdAvailable()) {
110 logger.debug("Set Power ON using Power command");
111 setSetting(SonyProjectorItem.POWER, POWER_ON);
113 logger.debug("Set Power ON using IR Power command");
114 sendIR(SonyProjectorItem.IR_POWER_ON);
115 if (status == null) {
116 sendIR(SonyProjectorItem.IR_POWER_ON);
122 * Power OFF the projector
124 * @throws SonyProjectorException - In case the projector is not ready for a power OFF command or any other problem
126 public void powerOff() throws SonyProjectorException {
127 SonyProjectorStatusPower status = null;
129 status = getStatusPower();
130 } catch (SonyProjectorException e) {
132 logger.debug("Current Power Status: {}", status == null ? "undefined" : status.getName());
133 if (status == null || status != SonyProjectorStatusPower.POWER_ON) {
134 throw new SonyProjectorException("Projector not ready for command OFF");
135 } else if (model.isPowerCmdAvailable()) {
136 logger.debug("Set Power OFF using Power command");
137 setSetting(SonyProjectorItem.POWER, POWER_OFF);
139 logger.debug("Set Power OFF using IR Power command");
140 sendIR(SonyProjectorItem.IR_POWER_OFF);
145 * Request the projector to get the current calibration preset
147 * @return the current calibration preset
149 * @throws SonyProjectorException - In case of any problem
151 public String getCalibrationPreset() throws SonyProjectorException {
152 return model.getCalibrPresetNameFromDataCode(getSetting(SonyProjectorItem.CALIBRATION_PRESET));
156 * Request the projector to change the calibration preset
158 * @param value the calibration preset to set
160 * @throws SonyProjectorException - In case of any problem
162 public void setCalibrationPreset(String value) throws SonyProjectorException {
163 setSetting(SonyProjectorItem.CALIBRATION_PRESET, model.getCalibrPresetDataCodeFromName(value));
167 * Request the projector to get the current video input
169 * @return the current video input
171 * @throws SonyProjectorException - In case of any problem
173 public String getInput() throws SonyProjectorException {
174 return model.getInputNameFromDataCode(getSetting(SonyProjectorItem.INPUT));
178 * Request the projector to change the video input
180 * @param value the video input to set
182 * @throws SonyProjectorException - In case of any problem
184 public void setInput(String value) throws SonyProjectorException {
185 setSetting(SonyProjectorItem.INPUT, model.getInputDataCodeFromName(value));
189 * Request the projector to get the current contrast setting
191 * @return the current contrast value
193 * @throws SonyProjectorException - In case of any problem
195 public int getContrast() throws SonyProjectorException {
196 return convertDataToInt(getSetting(SonyProjectorItem.CONTRAST));
200 * Request the projector to change the contrast setting
202 * @param value the contrast value to set
204 * @throws SonyProjectorException - In case of any problem
206 public void setContrast(int value) throws SonyProjectorException {
207 setSetting(SonyProjectorItem.CONTRAST, convertIntToData(value));
211 * Request the projector to get the current brightness setting
213 * @return the current brightness value
215 * @throws SonyProjectorException - In case of any problem
217 public int getBrightness() throws SonyProjectorException {
218 return convertDataToInt(getSetting(SonyProjectorItem.BRIGHTNESS));
222 * Request the projector to change the brightness setting
224 * @param value the brightness value to set
226 * @throws SonyProjectorException - In case of any problem
228 public void setBrightness(int value) throws SonyProjectorException {
229 setSetting(SonyProjectorItem.BRIGHTNESS, convertIntToData(value));
233 * Request the projector to get the current color setting
235 * @return the current color value
237 * @throws SonyProjectorException - In case of any problem
239 public int getColor() throws SonyProjectorException {
240 return convertDataToInt(getSetting(SonyProjectorItem.COLOR));
244 * Request the projector to change the color setting
246 * @param value the color value to set
248 * @throws SonyProjectorException - In case of any problem
250 public void setColor(int value) throws SonyProjectorException {
251 setSetting(SonyProjectorItem.COLOR, convertIntToData(value));
255 * Request the projector to get the current hue setting
257 * @return the current hue value
259 * @throws SonyProjectorException - In case of any problem
261 public int getHue() throws SonyProjectorException {
262 return convertDataToInt(getSetting(SonyProjectorItem.HUE));
266 * Request the projector to change the hue setting
268 * @param value the hue value to set
270 * @throws SonyProjectorException - In case of any problem
272 public void setHue(int value) throws SonyProjectorException {
273 setSetting(SonyProjectorItem.HUE, convertIntToData(value));
277 * Request the projector to get the current sharpness setting
279 * @return the current sharpness value
281 * @throws SonyProjectorException - In case of any problem
283 public int getSharpness() throws SonyProjectorException {
284 return convertDataToInt(getSetting(SonyProjectorItem.SHARPNESS));
288 * Request the projector to change the sharpness setting
290 * @param value the sharpness value to set
292 * @throws SonyProjectorException - In case of any problem
294 public void setSharpness(int value) throws SonyProjectorException {
295 setSetting(SonyProjectorItem.SHARPNESS, convertIntToData(value));
299 * Request the projector to get the current contrast enhancer mode
301 * @return the current contrast enhancer mode
303 * @throws SonyProjectorException - In case of any problem
305 public String getContrastEnhancer() throws SonyProjectorException {
306 return model.getContrastEnhancerNameFromDataCode(getSetting(SonyProjectorItem.CONTRAST_ENHANCER));
310 * Request the projector to change the contrast enhancer mode
312 * @param value the contrast enhancer mode to set
314 * @throws SonyProjectorException - In case of any problem
316 public void setContrastEnhancer(String value) throws SonyProjectorException {
317 setSetting(SonyProjectorItem.CONTRAST_ENHANCER, model.getContrastEnhancerDataCodeFromName(value));
321 * Request the projector to get the current film mode
323 * @return the current film mode
325 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
327 public String getFilmMode() throws SonyProjectorException {
328 if (!model.isFilmModeAvailable()) {
329 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.FILM_MODE.getName()
330 + " for projector model " + model.getName());
332 return model.getFilmModeNameFromDataCode(getSetting(SonyProjectorItem.FILM_MODE));
336 * Request the projector to change the film mode
338 * @param value the film mode to set
340 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
342 public void setFilmMode(String value) throws SonyProjectorException {
343 if (!model.isFilmModeAvailable()) {
344 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.FILM_MODE.getName()
345 + " for projector model " + model.getName());
347 setSetting(SonyProjectorItem.FILM_MODE, model.getFilmModeDataCodeFromName(value));
351 * Request the projector to get the lamp use time
353 * @return the lamp use time
355 * @throws SonyProjectorException - In case of any problem
357 public int getLampUseTime() throws SonyProjectorException {
358 return convertDataToInt(getSetting(SonyProjectorItem.LAMP_USE_TIME));
362 * Request the projector to get the current mode for the lamp control setting
364 * @return the current mode for the lamp control setting
366 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
368 public String getLampControl() throws SonyProjectorException {
369 if (!model.isLampControlAvailable()) {
370 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.LAMP_CONTROL.getName()
371 + " for projector model " + model.getName());
373 return SonyProjectorLampControl.getFromDataCode(getSetting(SonyProjectorItem.LAMP_CONTROL)).getName();
377 * Request the projector to change the mode for the lamp control setting
379 * @param value the mode to set for the lamp control setting
381 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
383 public void setLampControl(String value) throws SonyProjectorException {
384 if (!model.isLampControlAvailable()) {
385 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.LAMP_CONTROL.getName()
386 + " for projector model " + model.getName());
388 setSetting(SonyProjectorItem.LAMP_CONTROL, SonyProjectorLampControl.getFromName(value).getDataCode());
392 * Request the projector if the picture is muted or not
394 * @return OnOffType.ON if the picture is muted, OnOffType.OFF if not
396 * @throws SonyProjectorException - In case of any problem
398 public OnOffType getPictureMuting() throws SonyProjectorException {
399 return Arrays.equals(getSetting(SonyProjectorItem.PICTURE_MUTING), PICTURE_ON) ? OnOffType.ON : OnOffType.OFF;
403 * Request the projector to mute the picture
405 * @throws SonyProjectorException - In case of any problem
407 public void mutePicture() throws SonyProjectorException {
408 setSetting(SonyProjectorItem.PICTURE_MUTING, PICTURE_ON);
412 * Request the projector to unmute the picture
414 * @throws SonyProjectorException - In case of any problem
416 public void unmutePicture() throws SonyProjectorException {
417 setSetting(SonyProjectorItem.PICTURE_MUTING, PICTURE_OFF);
421 * Request the projector to get the current mode for the picture position setting
423 * @return the current mode for the picture position setting
425 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
427 public String getPicturePosition() throws SonyProjectorException {
428 if (!model.isPicturePositionAvailable()) {
429 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.PICTURE_POSITION.getName()
430 + " for projector model " + model.getName());
432 return model.getPicturePositionNameFromDataCode(getSetting(SonyProjectorItem.PICTURE_POSITION));
436 * Request the projector to change the mode for the picture position setting
438 * @param value the mode to set for the picture position setting
440 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
442 public void setPicturePosition(String value) throws SonyProjectorException {
443 if (!model.isPicturePositionAvailable()) {
444 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.PICTURE_POSITION.getName()
445 + " for projector model " + model.getName());
447 setSetting(SonyProjectorItem.PICTURE_POSITION, model.getPicturePositionCodeFromName(value));
451 * Request the projector if the overscan is enabled or not
453 * @return OnOffType.ON if the overscan is enabled, OnOffType.OFF if not
455 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
457 public OnOffType getOverscan() throws SonyProjectorException {
458 if (!model.isOverscanAvailable()) {
459 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.OVERSCAN.getName()
460 + " for projector model " + model.getName());
462 return Arrays.equals(getSetting(SonyProjectorItem.OVERSCAN), OVERSCAN_ON) ? OnOffType.ON : OnOffType.OFF;
466 * Request the projector to enable the overscan
468 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
470 public void enableOverscan() throws SonyProjectorException {
471 if (!model.isOverscanAvailable()) {
472 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.OVERSCAN.getName()
473 + " for projector model " + model.getName());
475 setSetting(SonyProjectorItem.OVERSCAN, OVERSCAN_ON);
479 * Request the projector to disable the overscan
481 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
483 public void disableOverscan() throws SonyProjectorException {
484 if (!model.isOverscanAvailable()) {
485 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.OVERSCAN.getName()
486 + " for projector model " + model.getName());
488 setSetting(SonyProjectorItem.OVERSCAN, OVERSCAN_OFF);
492 * Request the projector to get the current aspect ratio mode
494 * @return the current current aspect ratio mode
496 * @throws SonyProjectorException - In case of any problem
498 public String getAspect() throws SonyProjectorException {
499 return model.getAspectNameFromDataCode(getSetting(SonyProjectorItem.ASPECT));
503 * Request the projector to change the aspect ratio mode
505 * @param value the aspect ratio mode to set
507 * @throws SonyProjectorException - In case of any problem
509 public void setAspect(String value) throws SonyProjectorException {
510 setSetting(SonyProjectorItem.ASPECT, model.getAspectCodeFromName(value));
514 * Request the projector to get the current color temperature setting
516 * @return the current color temperature value
518 * @throws SonyProjectorException - In case of any problem
520 public String getColorTemperature() throws SonyProjectorException {
521 return model.getColorTempNameFromDataCode(getSetting(SonyProjectorItem.COLOR_TEMP));
525 * Request the projector to change the color temperature setting
527 * @param value the color temperature value to set
529 * @throws SonyProjectorException - In case of any problem
531 public void setColorTemperature(String value) throws SonyProjectorException {
532 setSetting(SonyProjectorItem.COLOR_TEMP, model.getColorTempCodeFromName(value));
536 * Request the projector to get the current iris mode
538 * @return the current iris mode
540 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
542 public String getIrisMode() throws SonyProjectorException {
543 if (!model.isIrisModeAvailable()) {
544 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.IRIS_MODE.getName()
545 + " for projector model " + model.getName());
547 return model.getIrisModeNameFromDataCode(getSetting(SonyProjectorItem.IRIS_MODE));
551 * Request the projector to change the iris mode
553 * @param value the iris mode to set
555 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
557 public void setIrisMode(String value) throws SonyProjectorException {
558 if (!model.isIrisModeAvailable()) {
559 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.IRIS_MODE.getName()
560 + " for projector model " + model.getName());
562 setSetting(SonyProjectorItem.IRIS_MODE, model.getIrisModeCodeFromName(value));
566 * Request the projector to get the current iris manual setting
568 * @return the current value for the iris manual setting
570 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
572 public int getIrisManual() throws SonyProjectorException {
573 if (!model.isIrisManualAvailable()) {
574 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.IRIS_MANUAL.getName()
575 + " for projector model " + model.getName());
577 return convertDataToInt(getSetting(SonyProjectorItem.IRIS_MANUAL));
581 * Request the projector to change the iris manual setting
583 * @param value the iris manual value to set
585 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
587 public void setIrisManual(int value) throws SonyProjectorException {
588 if (!model.isIrisManualAvailable()) {
589 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.IRIS_MANUAL.getName()
590 + " for projector model " + model.getName());
592 setSetting(SonyProjectorItem.IRIS_MANUAL, convertIntToData(value));
596 * Request the projector to get the current iris sensitivity
598 * @return the current iris sensitivity
600 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
602 public String getIrisSensitivity() throws SonyProjectorException {
603 if (!model.isIrisSensitivityAvailable()) {
604 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.IRIS_SENSITIVITY.getName()
605 + " for projector model " + model.getName());
607 return SonyProjectorIrisSensitivity.getFromDataCode(getSetting(SonyProjectorItem.IRIS_SENSITIVITY)).getName();
611 * Request the projector to change the iris sensitivity
613 * @param value the iris sensitivity to set
615 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
617 public void setIrisSensitivity(String value) throws SonyProjectorException {
618 if (!model.isIrisSensitivityAvailable()) {
619 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.IRIS_SENSITIVITY.getName()
620 + " for projector model " + model.getName());
622 setSetting(SonyProjectorItem.IRIS_SENSITIVITY, SonyProjectorIrisSensitivity.getFromName(value).getDataCode());
626 * Request the projector to get the current film projection mode
628 * @return the current film projection mode
630 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
632 public String getFilmProjection() throws SonyProjectorException {
633 if (!model.isFilmProjectionAvailable()) {
634 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.FILM_PROJECTION.getName()
635 + " for projector model " + model.getName());
637 return model.getFilmProjectionNameFromDataCode(getSetting(SonyProjectorItem.FILM_PROJECTION));
641 * Request the projector to change the film projection mode
643 * @param value the film projection mode to set
645 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
647 public void setFilmProjection(String value) throws SonyProjectorException {
648 if (!model.isFilmProjectionAvailable()) {
649 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.FILM_PROJECTION.getName()
650 + " for projector model " + model.getName());
652 setSetting(SonyProjectorItem.FILM_PROJECTION, model.getFilmProjectionCodeFromName(value));
656 * Request the projector to get the current motion enhancer mode
658 * @return the current motion enhancer mode
660 * @throws SonyProjectorException - In case of any problem
662 public String getMotionEnhancer() throws SonyProjectorException {
663 if (!model.isMotionEnhancerAvailable()) {
664 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.MOTION_ENHANCER.getName()
665 + " for projector model " + model.getName());
667 return model.getMotionEnhancerNameFromDataCode(getSetting(SonyProjectorItem.MOTION_ENHANCER));
671 * Request the projector to change the motion enhancer mode
673 * @param value the motion enhancer mode to set
675 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
677 public void setMotionEnhancer(String value) throws SonyProjectorException {
678 if (!model.isMotionEnhancerAvailable()) {
679 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.MOTION_ENHANCER.getName()
680 + " for projector model " + model.getName());
682 setSetting(SonyProjectorItem.MOTION_ENHANCER, model.getMotionEnhancerCodeFromName(value));
686 * Request the projector to get the current gamma correction
688 * @return the current gamma correction
690 * @throws SonyProjectorException - In case of any problem
692 public String getGammaCorrection() throws SonyProjectorException {
693 return model.getGammaCorrectionNameFromDataCode(getSetting(SonyProjectorItem.GAMMA_CORRECTION));
697 * Request the projector to change the gamma correction
699 * @param value the gamma correction to set
701 * @throws SonyProjectorException - In case of any problem
703 public void setGammaCorrection(String value) throws SonyProjectorException {
704 setSetting(SonyProjectorItem.GAMMA_CORRECTION, model.getGammaCorrectionCodeFromName(value));
708 * Request the projector to get the current color space
710 * @return the current color space
712 * @throws SonyProjectorException - In case of any problem
714 public String getColorSpace() throws SonyProjectorException {
715 return model.getColorSpaceNameFromDataCode(getSetting(SonyProjectorItem.COLOR_SPACE));
719 * Request the projector to change the color space
721 * @param value the color space to set
723 * @throws SonyProjectorException - In case of any problem
725 public void setColorSpace(String value) throws SonyProjectorException {
726 setSetting(SonyProjectorItem.COLOR_SPACE, model.getColorSpaceCodeFromName(value));
730 * Request the projector to get the current noise reduction mode
732 * @return the current noise reduction mode
734 * @throws SonyProjectorException - In case of any problem
736 public String getNr() throws SonyProjectorException {
737 return model.getNrNameFromDataCode(getSetting(SonyProjectorItem.NR));
741 * Request the projector to change the noise reduction mode
743 * @param value the noise reduction mode to set
745 * @throws SonyProjectorException - In case of any problem
747 public void setNr(String value) throws SonyProjectorException {
748 setSetting(SonyProjectorItem.NR, model.getNrCodeFromName(value));
752 * Request the projector to get the current block noise reduction mode
754 * @return the current block noise reduction mode
756 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
758 public String getBlockNr() throws SonyProjectorException {
759 if (!model.isBlockNrAvailable()) {
760 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.BLOCK_NR.getName()
761 + " for projector model " + model.getName());
763 return SonyProjectorBlockNr.getFromDataCode(getSetting(SonyProjectorItem.BLOCK_NR)).getName();
767 * Request the projector to change the block noise reduction mode
769 * @param value the block noise reduction mode to set
771 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
773 public void setBlockNr(String value) throws SonyProjectorException {
774 if (!model.isBlockNrAvailable()) {
775 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.BLOCK_NR.getName()
776 + " for projector model " + model.getName());
778 setSetting(SonyProjectorItem.BLOCK_NR, SonyProjectorBlockNr.getFromName(value).getDataCode());
782 * Request the projector to get the current mosquito noise reduction mode
784 * @return the current mosquito noise reduction mode
786 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
788 public String getMosquitoNr() throws SonyProjectorException {
789 if (!model.isMosquitoNrAvailable()) {
790 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.MOSQUITO_NR.getName()
791 + " for projector model " + model.getName());
793 return SonyProjectorMosquitoNr.getFromDataCode(getSetting(SonyProjectorItem.MOSQUITO_NR)).getName();
797 * Request the projector to change the mosquito noise reduction mode
799 * @param value the mosquito noise reduction mode to set
801 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
803 public void setMosquitoNr(String value) throws SonyProjectorException {
804 if (!model.isMosquitoNrAvailable()) {
805 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.MOSQUITO_NR.getName()
806 + " for projector model " + model.getName());
808 setSetting(SonyProjectorItem.MOSQUITO_NR, SonyProjectorMosquitoNr.getFromName(value).getDataCode());
812 * Request the projector to get the current MPEG noise reduction mode
814 * @return the current MPEG noise reduction mode
816 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
818 public String getMpegNr() throws SonyProjectorException {
819 if (!model.isMpegNrAvailable()) {
820 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.MPEG_NR.getName()
821 + " for projector model " + model.getName());
823 return model.getMpegNrNameFromDataCode(getSetting(SonyProjectorItem.MPEG_NR));
827 * Request the projector to change the MPEG noise reduction mode
829 * @param value the MPEG noise reduction mode to set
831 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
833 public void setMpegNr(String value) throws SonyProjectorException {
834 if (!model.isMpegNrAvailable()) {
835 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.MPEG_NR.getName()
836 + " for projector model " + model.getName());
838 setSetting(SonyProjectorItem.MPEG_NR, model.getMpegNrCodeFromName(value));
842 * Request the projector to get the current value for xvColor
844 * @return the current value for xvColor
846 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
848 public OnOffType getXvColor() throws SonyProjectorException {
849 if (!model.isXvColorAvailable()) {
850 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.XVCOLOR.getName()
851 + " for projector model " + model.getName());
853 return Arrays.equals(getSetting(SonyProjectorItem.XVCOLOR), XVCOLOR_ON) ? OnOffType.ON : OnOffType.OFF;
857 * Request the projector to set xvColor to ON
859 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
861 public void enableXvColor() throws SonyProjectorException {
862 if (!model.isXvColorAvailable()) {
863 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.XVCOLOR.getName()
864 + " for projector model " + model.getName());
866 setSetting(SonyProjectorItem.XVCOLOR, XVCOLOR_ON);
870 * Request the projector to set xvColor to OFF
872 * @throws SonyProjectorException - In case this setting is not available for the projector or any other problem
874 public void disableXvColor() throws SonyProjectorException {
875 if (!model.isXvColorAvailable()) {
876 throw new SonyProjectorException("Unavailable item " + SonyProjectorItem.XVCOLOR.getName()
877 + " for projector model " + model.getName());
879 setSetting(SonyProjectorItem.XVCOLOR, XVCOLOR_OFF);
883 * Request the projector to get the current value for a setting
885 * @param item the projector setting to get
887 * @return the current value for the setting
889 * @throws SonyProjectorException - In case of any problem
891 protected byte[] getSetting(SonyProjectorItem item) throws SonyProjectorException {
892 logger.debug("Get setting {}", item.getName());
895 byte[] result = getResponseData(executeCommand(item, true, DUMMY_DATA));
897 logger.debug("Get setting {} succeeded: result data: {}", item.getName(), HexUtils.bytesToHex(result));
900 } catch (SonyProjectorException e) {
901 logger.debug("Get setting {} failed: {}", item.getName(), e.getMessage());
902 throw new SonyProjectorException("Get setting " + item.getName() + " failed: " + e.getMessage());
907 * Request the projector to set a new value for a setting
909 * @param item the projector setting to set
910 * @param data the value to set for the setting
912 * @throws SonyProjectorException - In case of any problem
914 private void setSetting(SonyProjectorItem item, byte[] data) throws SonyProjectorException {
915 logger.debug("Set setting {} data {}", item.getName(), HexUtils.bytesToHex(data));
918 executeCommand(item, false, data);
919 } catch (SonyProjectorException e) {
920 logger.debug("Set setting {} failed: {}", item.getName(), e.getMessage());
921 throw new SonyProjectorException("Set setting " + item.getName() + " failed: " + e.getMessage());
924 logger.debug("Set setting {} succeeded", item.getName());
928 * Send an IR command to the projector
930 * @param item the IR information to send
932 * @throws SonyProjectorException - In case of any problem
934 private synchronized void sendIR(SonyProjectorItem item) throws SonyProjectorException {
935 logger.debug("Send IR {}", item.getName());
938 boolean runningSession = connected;
942 // Build the message and send it
943 writeCommand(buildMessage(item, false, DUMMY_DATA));
945 // Wait at least 45 ms
948 // No response expected for SIRCS commands
950 if (!runningSession) {
953 } catch (SonyProjectorException | InterruptedException e) {
954 logger.debug("Send IR {} failed: {}", item.getName(), e.getMessage());
955 throw new SonyProjectorException("Send IR " + item.getName() + " failed: " + e.getMessage());
958 logger.debug("Send IR {} succeeded", item.getName());
962 * Connect to the projector, write a command, read the response and disconnect
964 * @param item the projector setting to get or set
965 * @param getCommand true for a GET command or false for a SET command
966 * @param data the value to be considered in case of a SET command
968 * @return the buffer containing the returned message
970 * @throws SonyProjectorException - In case of any problem
972 private synchronized byte[] executeCommand(SonyProjectorItem item, boolean getCommand, byte[] data)
973 throws SonyProjectorException {
975 boolean runningSession = connected;
979 // Build the message and send it
980 writeCommand(buildMessage(item, getCommand, data));
983 byte[] responseMessage = readResponse();
985 if (!runningSession) {
989 // Validate the content of the response
990 validateResponse(responseMessage, item);
992 return responseMessage;
993 } catch (SonyProjectorException e) {
994 throw new SonyProjectorException(e.getMessage());
999 * Open the connection with the projector if not yet opened
1001 * @throws SonyProjectorException - In case of any problem
1003 public abstract void open() throws SonyProjectorException;
1006 * Close the connection with the projector
1008 public void close() {
1010 OutputStream dataOut = this.dataOut;
1011 if (dataOut != null) {
1014 } catch (IOException e) {
1016 this.dataOut = null;
1018 InputStream dataIn = this.dataIn;
1019 if (dataIn != null) {
1022 } catch (IOException e) {
1031 * Build the message buffer corresponding to the request of a particular information
1033 * @param item the projector setting to get or set
1034 * @param getCommand true for a GET command or false for a SET command
1035 * @param data the value to be considered in case of a SET command
1037 * @return the message buffer
1039 protected abstract byte[] buildMessage(SonyProjectorItem item, boolean getCommand, byte[] data);
1042 * Reads some number of bytes from the input stream and stores them into the buffer array b. The number of bytes
1043 * actually read is returned as an integer.
1045 * @param dataBuffer the buffer into which the data is read.
1046 * @return the total number of bytes read into the buffer, or -1 if there is no more data because the end of the
1047 * stream has been reached.
1048 * @throws SonyProjectorException - If the input stream is null, if the first byte cannot be read for any reason
1049 * other than the end of the file, if the input stream has been closed, or if some other I/O error
1052 protected int readInput(byte[] dataBuffer) throws SonyProjectorException {
1054 throw new SonyProjectorException("readInput failed: should not be called in simu mode");
1056 InputStream dataIn = this.dataIn;
1057 if (dataIn == null) {
1058 throw new SonyProjectorException("readInput failed: input stream is null");
1061 return dataIn.read(dataBuffer);
1062 } catch (IOException e) {
1063 logger.debug("readInput failed: {}", e.getMessage());
1064 throw new SonyProjectorException("readInput failed: " + e.getMessage());
1069 * Write a command to the output stream
1071 * @param message the buffer containing the message to be sent
1073 * @throws SonyProjectorException - In case of any communication problem
1075 protected void writeCommand(byte[] message) throws SonyProjectorException {
1076 logger.debug("writeCommand: {}", HexUtils.bytesToHex(message));
1080 OutputStream dataOut = this.dataOut;
1081 if (dataOut == null) {
1082 throw new SonyProjectorException("writeCommand failed: output stream is null");
1085 dataOut.write(message);
1087 } catch (IOException e) {
1088 logger.debug("writeCommand failed: {}", e.getMessage());
1089 throw new SonyProjectorException("writeCommand failed: " + e.getMessage());
1094 * Read the response from the input stream
1096 * @return the buffer containing the returned message
1098 * @throws SonyProjectorException - In case of any communication problem
1100 protected abstract byte[] readResponse() throws SonyProjectorException;
1103 * Validate the content of a returned message
1105 * @param responseMessage the buffer containing the returned message
1106 * @param the projector setting to get or set
1108 * @throws SonyProjectorException - If the message has unexpected content
1110 protected abstract void validateResponse(byte[] responseMessage, SonyProjectorItem item)
1111 throws SonyProjectorException;
1114 * Extract the value from the returned message
1116 * @param responseMessage the buffer containing the returned message
1118 * @return the value of the projector setting that was requested
1120 protected abstract byte[] getResponseData(byte[] responseMessage);
1122 private int convertDataToInt(byte[] data) {
1123 return ((data[0] & 0x000000FF) << 8) | (data[1] & 0x000000FF);
1126 private byte[] convertIntToData(int value) {
1127 byte[] data = new byte[2];
1128 data[0] = (byte) ((value & 0x0000FF00) >> 8);
1129 data[1] = (byte) (value & 0x000000FF);