2 * Copyright (c) 2010-2023 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.handler;
15 import static org.openhab.binding.sonyprojector.internal.SonyProjectorBindingConstants.*;
17 import java.util.concurrent.ScheduledFuture;
18 import java.util.concurrent.TimeUnit;
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.binding.sonyprojector.internal.SonyProjectorStateDescriptionOptionProvider;
25 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorConnector;
26 import org.openhab.binding.sonyprojector.internal.communication.SonyProjectorStatusPower;
27 import org.openhab.binding.sonyprojector.internal.communication.sdcp.SonyProjectorSdcpConnector;
28 import org.openhab.binding.sonyprojector.internal.communication.sdcp.SonyProjectorSdcpSimuConnector;
29 import org.openhab.binding.sonyprojector.internal.communication.serial.SonyProjectorSerialConnector;
30 import org.openhab.binding.sonyprojector.internal.communication.serial.SonyProjectorSerialOverIpConnector;
31 import org.openhab.binding.sonyprojector.internal.communication.serial.SonyProjectorSerialSimuConnector;
32 import org.openhab.binding.sonyprojector.internal.configuration.SonyProjectorEthernetConfiguration;
33 import org.openhab.binding.sonyprojector.internal.configuration.SonyProjectorSerialConfiguration;
34 import org.openhab.binding.sonyprojector.internal.configuration.SonyProjectorSerialOverIpConfiguration;
35 import org.openhab.core.cache.ExpiringCacheMap;
36 import org.openhab.core.i18n.ConnectionException;
37 import org.openhab.core.i18n.TranslationProvider;
38 import org.openhab.core.io.transport.serial.SerialPortManager;
39 import org.openhab.core.library.types.DecimalType;
40 import org.openhab.core.library.types.OnOffType;
41 import org.openhab.core.library.types.PercentType;
42 import org.openhab.core.library.types.StringType;
43 import org.openhab.core.thing.ChannelUID;
44 import org.openhab.core.thing.Thing;
45 import org.openhab.core.thing.ThingStatus;
46 import org.openhab.core.thing.ThingStatusDetail;
47 import org.openhab.core.thing.binding.BaseThingHandler;
48 import org.openhab.core.types.Command;
49 import org.openhab.core.types.RefreshType;
50 import org.openhab.core.types.State;
51 import org.openhab.core.types.UnDefType;
52 import org.osgi.framework.Bundle;
53 import org.osgi.framework.FrameworkUtil;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
58 * The {@link SonyProjectorHandler} is responsible for handling commands, which are
59 * sent to one of the channels.
61 * @author Markus Wehrle - Initial contribution
62 * @author Laurent Garnier - Refactoring, poll thread for regular channels updates, new serial thing type, new channels
65 public class SonyProjectorHandler extends BaseThingHandler {
67 private static final SonyProjectorModel DEFAULT_MODEL = SonyProjectorModel.VW520;
68 private static final long POLLING_INTERVAL = TimeUnit.SECONDS.toSeconds(15);
70 private final Logger logger = LoggerFactory.getLogger(SonyProjectorHandler.class);
72 private final SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider;
73 private final SerialPortManager serialPortManager;
74 private final TranslationProvider i18nProvider;
76 private final Bundle bundle;
78 private final ExpiringCacheMap<String, State> cache;
80 private @Nullable ScheduledFuture<?> refreshJob;
82 private boolean identifyProjector;
83 private SonyProjectorModel projectorModel = DEFAULT_MODEL;
84 private SonyProjectorConnector connector = new SonyProjectorSdcpSimuConnector(DEFAULT_MODEL);
88 private final Object commandLock = new Object();
90 public SonyProjectorHandler(Thing thing, SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider,
91 SerialPortManager serialPortManager, TranslationProvider i18nProvider) {
93 this.stateDescriptionProvider = stateDescriptionProvider;
94 this.serialPortManager = serialPortManager;
95 this.i18nProvider = i18nProvider;
96 this.bundle = FrameworkUtil.getBundle(this.getClass());
97 this.cache = new ExpiringCacheMap<>(TimeUnit.SECONDS.toMillis(POLLING_INTERVAL));
101 public void handleCommand(ChannelUID channelUID, Command command) {
102 String channel = channelUID.getId();
103 if (command instanceof RefreshType) {
104 State state = cache.get(channel);
106 updateState(channel, state);
111 synchronized (commandLock) {
114 } catch (ConnectionException e) {
115 logger.debug("Command {} from channel {} failed: {}", command, channel,
116 e.getMessage(bundle, i18nProvider));
117 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getRawMessage());
123 if (command == OnOffType.ON) {
125 } else if (command == OnOffType.OFF) {
126 connector.powerOff();
128 throw new SonyProjectorException("Invalid command value");
132 connector.setInput(command.toString());
134 case CHANNEL_CALIBRATION_PRESET:
135 connector.setCalibrationPreset(command.toString());
136 refreshChannel(CHANNEL_CONTRAST, true);
137 refreshChannel(CHANNEL_BRIGHTNESS, true);
138 refreshChannel(CHANNEL_COLOR, true);
139 refreshChannel(CHANNEL_HUE, true);
140 refreshChannel(CHANNEL_SHARPNESS, true);
141 refreshChannel(CHANNEL_COLOR_TEMP, true);
142 refreshChannel(CHANNEL_IRIS_MODE, true);
143 refreshChannel(CHANNEL_IRIS_MANUAL, true);
144 refreshChannel(CHANNEL_IRIS_SENSITIVITY, true);
145 refreshChannel(CHANNEL_LAMP_CONTROL, true);
146 refreshChannel(CHANNEL_FILM_PROJECTION, true);
147 refreshChannel(CHANNEL_MOTION_ENHANCER, true);
148 refreshChannel(CHANNEL_CONTRAST_ENHANCER, true);
149 refreshChannel(CHANNEL_FILM_MODE, true);
150 refreshChannel(CHANNEL_GAMMA_CORRECTION, true);
151 refreshChannel(CHANNEL_COLOR_SPACE, true);
152 refreshChannel(CHANNEL_NR, true);
153 refreshChannel(CHANNEL_BLOCK_NR, true);
154 refreshChannel(CHANNEL_MOSQUITO_NR, true);
155 refreshChannel(CHANNEL_MPEG_NR, true);
156 refreshChannel(CHANNEL_XVCOLOR, true);
158 case CHANNEL_CONTRAST:
159 if (command instanceof DecimalType) {
160 connector.setContrast(((DecimalType) command).intValue());
161 } else if (command instanceof PercentType) {
162 connector.setContrast(((PercentType) command).intValue());
164 throw new SonyProjectorException("Invalid command value");
167 case CHANNEL_BRIGHTNESS:
168 if (command instanceof DecimalType) {
169 connector.setBrightness(((DecimalType) command).intValue());
170 } else if (command instanceof PercentType) {
171 connector.setBrightness(((PercentType) command).intValue());
173 throw new SonyProjectorException("Invalid command value");
177 if (command instanceof DecimalType) {
178 connector.setColor(((DecimalType) command).intValue());
179 } else if (command instanceof PercentType) {
180 connector.setColor(((PercentType) command).intValue());
182 throw new SonyProjectorException("Invalid command value");
186 if (command instanceof DecimalType) {
187 connector.setHue(((DecimalType) command).intValue());
188 } else if (command instanceof PercentType) {
189 connector.setHue(((PercentType) command).intValue());
191 throw new SonyProjectorException("Invalid command value");
194 case CHANNEL_SHARPNESS:
195 if (command instanceof DecimalType) {
196 connector.setSharpness(((DecimalType) command).intValue());
197 } else if (command instanceof PercentType) {
198 connector.setSharpness(((PercentType) command).intValue());
200 throw new SonyProjectorException("Invalid command value");
203 case CHANNEL_COLOR_TEMP:
204 connector.setColorTemperature(command.toString());
206 case CHANNEL_IRIS_MODE:
207 connector.setIrisMode(command.toString());
208 refreshChannel(CHANNEL_IRIS_MANUAL, true);
210 case CHANNEL_IRIS_MANUAL:
211 if (command instanceof DecimalType) {
212 connector.setIrisManual(((DecimalType) command).intValue());
213 } else if (command instanceof PercentType) {
214 connector.setIrisManual(((PercentType) command).intValue());
216 throw new SonyProjectorException("Invalid command value");
219 case CHANNEL_IRIS_SENSITIVITY:
220 connector.setIrisSensitivity(command.toString());
222 case CHANNEL_LAMP_CONTROL:
223 connector.setLampControl(command.toString());
225 case CHANNEL_FILM_PROJECTION:
226 connector.setFilmProjection(command.toString());
228 case CHANNEL_MOTION_ENHANCER:
229 connector.setMotionEnhancer(command.toString());
231 case CHANNEL_CONTRAST_ENHANCER:
232 connector.setContrastEnhancer(command.toString());
234 case CHANNEL_FILM_MODE:
235 connector.setFilmMode(command.toString());
237 case CHANNEL_GAMMA_CORRECTION:
238 connector.setGammaCorrection(command.toString());
240 case CHANNEL_COLOR_SPACE:
241 connector.setColorSpace(command.toString());
244 connector.setNr(command.toString());
246 case CHANNEL_BLOCK_NR:
247 connector.setBlockNr(command.toString());
249 case CHANNEL_MOSQUITO_NR:
250 connector.setMosquitoNr(command.toString());
252 case CHANNEL_MPEG_NR:
253 connector.setMpegNr(command.toString());
255 case CHANNEL_XVCOLOR:
256 if (command == OnOffType.ON) {
257 connector.enableXvColor();
258 refreshChannel(CHANNEL_GAMMA_CORRECTION, true);
259 } else if (command == OnOffType.OFF) {
260 connector.disableXvColor();
261 refreshChannel(CHANNEL_GAMMA_CORRECTION, true);
263 throw new SonyProjectorException("Invalid command value");
266 case CHANNEL_PICTURE_MUTING:
267 if (command == OnOffType.ON) {
268 connector.mutePicture();
269 } else if (command == OnOffType.OFF) {
270 connector.unmutePicture();
272 throw new SonyProjectorException("Invalid command value");
276 connector.setAspect(command.toString());
278 case CHANNEL_OVERSCAN:
279 if (command == OnOffType.ON) {
280 connector.enableOverscan();
281 } else if (command == OnOffType.OFF) {
282 connector.disableOverscan();
284 throw new SonyProjectorException("Invalid command value");
287 case CHANNEL_PICTURE_POSITION:
288 connector.setPicturePosition(command.toString());
291 throw new SonyProjectorException("Unexpected command");
293 logger.debug("Command {} from channel {} succeeded", command, channel);
294 } catch (SonyProjectorException e) {
295 logger.debug("Command {} from channel {} failed: {}", command, channel, e.getMessage());
296 refreshChannel(channel, true);
303 public void initialize() {
304 logger.debug("Start initializing handler for thing {}", getThing().getUID());
306 boolean configOk = false;
308 if (getThing().getThingTypeUID().equals(THING_TYPE_ETHERNET)) {
309 SonyProjectorEthernetConfiguration config = getConfigAs(SonyProjectorEthernetConfiguration.class);
310 String configModel = config.model;
311 logger.debug("Ethernet config host {}", config.host);
312 logger.debug("Ethernet config port {}", config.port);
313 logger.debug("Ethernet config model {}", configModel);
314 logger.debug("Ethernet config community {}", config.community);
315 if (config.host == null || config.host.isEmpty()) {
316 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
317 "@text/offline.config-error-unknown-host");
318 } else if (configModel == null || configModel.isEmpty()) {
319 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
320 "@text/offline.config-error-unknown-model");
324 connector = simu ? new SonyProjectorSdcpSimuConnector(DEFAULT_MODEL)
325 : new SonyProjectorSdcpConnector(config.host, config.port, config.community, DEFAULT_MODEL);
326 identifyProjector = "AUTO".equals(configModel);
327 projectorModel = switchToModel("AUTO".equals(configModel) ? null : configModel, true);
329 updateStatus(ThingStatus.UNKNOWN);
331 } else if (getThing().getThingTypeUID().equals(THING_TYPE_SERIAL)) {
332 SonyProjectorSerialConfiguration config = getConfigAs(SonyProjectorSerialConfiguration.class);
333 String configModel = config.model;
334 logger.debug("Serial config port {}", config.port);
335 logger.debug("Serial config model {}", configModel);
336 if (config.port == null || config.port.isEmpty()) {
337 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
338 "@text/offline.config-error-unknown-port");
339 } else if (config.port.toLowerCase().startsWith("rfc2217")) {
340 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
341 "@text/offline.config-error-invalid-thing-type");
342 } else if (configModel == null || configModel.isEmpty()) {
343 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
344 "@text/offline.config-error-unknown-model");
348 connector = simu ? new SonyProjectorSerialSimuConnector(serialPortManager, DEFAULT_MODEL)
349 : new SonyProjectorSerialConnector(serialPortManager, config.port, DEFAULT_MODEL);
350 identifyProjector = false;
351 projectorModel = switchToModel(configModel, true);
353 updateStatus(ThingStatus.UNKNOWN);
355 } else if (getThing().getThingTypeUID().equals(THING_TYPE_SERIAL_OVER_IP)) {
356 SonyProjectorSerialOverIpConfiguration config = getConfigAs(SonyProjectorSerialOverIpConfiguration.class);
357 String configModel = config.model;
358 logger.debug("Serial over IP config host {}", config.host);
359 logger.debug("Serial over IP config port {}", config.port);
360 logger.debug("Serial over IP config model {}", configModel);
361 if (config.host == null || config.host.isEmpty()) {
362 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
363 "@text/offline.config-error-unknown-host");
364 } else if (config.port == null) {
365 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
366 "@text/offline.config-error-unknown-port");
367 } else if (config.port <= 0) {
368 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
369 "@text/offline.config-error-invalid-port");
370 } else if (configModel == null || configModel.isEmpty()) {
371 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
372 "@text/offline.config-error-unknown-model");
376 connector = simu ? new SonyProjectorSerialSimuConnector(serialPortManager, DEFAULT_MODEL)
377 : new SonyProjectorSerialOverIpConnector(serialPortManager, config.host, config.port,
379 identifyProjector = false;
380 projectorModel = switchToModel(configModel, true);
382 updateStatus(ThingStatus.UNKNOWN);
387 connector = new SonyProjectorSdcpSimuConnector(DEFAULT_MODEL);
389 ScheduledFuture<?> refreshJob = this.refreshJob;
390 if (refreshJob == null || refreshJob.isCancelled()) {
391 this.refreshJob = scheduler.scheduleWithFixedDelay(() -> {
393 }, 1, POLLING_INTERVAL, TimeUnit.SECONDS);
397 logger.debug("Finished initializing!");
401 public void dispose() {
402 logger.debug("Disposing handler for thing {}", getThing().getUID());
403 ScheduledFuture<?> refreshJob = this.refreshJob;
404 if (refreshJob != null && !refreshJob.isCancelled()) {
405 refreshJob.cancel(true);
406 this.refreshJob = null;
412 private void pollProjector() {
413 synchronized (commandLock) {
414 logger.debug("Polling the projector to refresh the channels...");
418 } catch (ConnectionException e) {
419 logger.debug("Poll projector failed: {}", e.getMessage(bundle, i18nProvider), e);
420 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getRawMessage());
424 boolean isOn = refreshPowerState();
426 refreshChannel(CHANNEL_INPUT, isOn);
427 refreshChannel(CHANNEL_CALIBRATION_PRESET, isOn);
428 refreshChannel(CHANNEL_CONTRAST, isOn);
429 refreshChannel(CHANNEL_BRIGHTNESS, isOn);
430 refreshChannel(CHANNEL_COLOR, isOn);
431 refreshChannel(CHANNEL_HUE, isOn);
432 refreshChannel(CHANNEL_SHARPNESS, isOn);
433 refreshChannel(CHANNEL_COLOR_TEMP, isOn);
434 refreshChannel(CHANNEL_IRIS_MODE, isOn);
435 refreshChannel(CHANNEL_IRIS_MANUAL, isOn);
436 refreshChannel(CHANNEL_IRIS_SENSITIVITY, isOn);
437 refreshChannel(CHANNEL_LAMP_CONTROL, isOn);
438 refreshChannel(CHANNEL_FILM_PROJECTION, isOn);
439 refreshChannel(CHANNEL_MOTION_ENHANCER, isOn);
440 refreshChannel(CHANNEL_CONTRAST_ENHANCER, isOn);
441 refreshChannel(CHANNEL_FILM_MODE, isOn);
442 refreshChannel(CHANNEL_GAMMA_CORRECTION, isOn);
443 refreshChannel(CHANNEL_COLOR_SPACE, isOn);
444 refreshChannel(CHANNEL_NR, isOn);
445 refreshChannel(CHANNEL_BLOCK_NR, isOn);
446 refreshChannel(CHANNEL_MOSQUITO_NR, isOn);
447 refreshChannel(CHANNEL_MPEG_NR, isOn);
448 refreshChannel(CHANNEL_XVCOLOR, isOn);
449 refreshChannel(CHANNEL_PICTURE_MUTING, isOn);
450 refreshChannel(CHANNEL_ASPECT, isOn);
451 refreshChannel(CHANNEL_OVERSCAN, isOn);
452 refreshChannel(CHANNEL_PICTURE_POSITION, isOn);
453 refreshChannel(CHANNEL_LAMP_USE_TIME, isOn);
457 updateStatus(ThingStatus.ONLINE);
459 logger.debug("End of the polling thread");
463 private void refreshModel() {
464 if (identifyProjector && getThing().getThingTypeUID().equals(THING_TYPE_ETHERNET)) {
466 String modelName = ((SonyProjectorSdcpConnector) connector).getModelName();
467 logger.debug("getModelName returned {}", modelName);
468 identifyProjector = false;
469 switchToModel(modelName, false);
470 } catch (SonyProjectorException e) {
471 logger.debug("getModelName failed: {}", e.getMessage());
476 private SonyProjectorModel switchToModel(@Nullable String modelName, boolean force) {
477 SonyProjectorModel model = DEFAULT_MODEL;
478 if (modelName != null && !modelName.isEmpty()) {
480 model = SonyProjectorModel.getFromName(modelName, false);
481 logger.debug("Model found: {}", model.getName());
482 } catch (SonyProjectorException e) {
483 logger.info("Model {} is unknow; consider {} by default", modelName, DEFAULT_MODEL.getName());
486 if (force || !model.getName().equals(projectorModel.getName())) {
487 connector.setModel(model);
488 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_INPUT),
489 model.getInputStateOptions());
490 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_CALIBRATION_PRESET),
491 model.getCalibrPresetStateOptions());
492 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_COLOR_TEMP),
493 model.getColorTempStateOptions());
494 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_IRIS_MODE),
495 model.getIrisModeStateOptions());
496 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_IRIS_SENSITIVITY),
497 model.getIrisSensitivityStateOptions());
498 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_LAMP_CONTROL),
499 model.getLampControlStateOptions());
500 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_FILM_PROJECTION),
501 model.getFilmProjectionStateOptions());
502 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_MOTION_ENHANCER),
503 model.getMotionEnhancerStateOptions());
504 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_CONTRAST_ENHANCER),
505 model.getContrastEnhancerStateOptions());
506 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_FILM_MODE),
507 model.getFilmModeStateOptions());
508 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_GAMMA_CORRECTION),
509 model.getGammaCorrectionStateOptions());
510 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_COLOR_SPACE),
511 model.getColorSpaceStateOptions());
512 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_NR),
513 model.getNrStateOptions());
514 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_BLOCK_NR),
515 model.getBlockNrStateOptions());
516 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_MOSQUITO_NR),
517 model.getMosquitoNrStateOptions());
518 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_MPEG_NR),
519 model.getMpegNrStateOptions());
520 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_ASPECT),
521 model.getAspectStateOptions());
522 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_PICTURE_POSITION),
523 model.getPicturePositionStateOptions());
528 private boolean refreshPowerState() {
530 State state = UnDefType.UNDEF;
532 SonyProjectorStatusPower value = connector.getStatusPower();
533 logger.debug("Get Status Power returned {}", value);
535 state = new StringType(value.name());
536 } catch (SonyProjectorException e) {
537 logger.debug("Get Status Power failed: {}", e.getMessage());
539 updateChannelStateAndCache(CHANNEL_POWER, on ? OnOffType.ON : OnOffType.OFF);
540 updateChannelStateAndCache(CHANNEL_POWERSTATE, state);
544 private @Nullable State requestProjectorValue(String channel, boolean requestValue) {
549 case CHANNEL_POWERSTATE:
551 case CHANNEL_CALIBRATION_PRESET:
552 case CHANNEL_CONTRAST:
553 case CHANNEL_BRIGHTNESS:
556 case CHANNEL_SHARPNESS:
557 case CHANNEL_COLOR_TEMP:
558 case CHANNEL_CONTRAST_ENHANCER:
559 case CHANNEL_GAMMA_CORRECTION:
560 case CHANNEL_COLOR_SPACE:
562 case CHANNEL_PICTURE_MUTING:
566 case CHANNEL_IRIS_MODE:
567 precond = projectorModel.isIrisModeAvailable();
569 case CHANNEL_IRIS_MANUAL:
570 precond = projectorModel.isIrisManualAvailable();
572 case CHANNEL_IRIS_SENSITIVITY:
573 precond = projectorModel.isIrisSensitivityAvailable();
575 case CHANNEL_LAMP_CONTROL:
576 precond = projectorModel.isLampControlAvailable();
578 case CHANNEL_FILM_PROJECTION:
579 precond = projectorModel.isFilmProjectionAvailable();
581 case CHANNEL_MOTION_ENHANCER:
582 precond = projectorModel.isMotionEnhancerAvailable();
584 case CHANNEL_FILM_MODE:
585 precond = projectorModel.isFilmModeAvailable();
587 case CHANNEL_BLOCK_NR:
588 precond = projectorModel.isBlockNrAvailable();
590 case CHANNEL_MOSQUITO_NR:
591 precond = projectorModel.isMosquitoNrAvailable();
593 case CHANNEL_MPEG_NR:
594 precond = projectorModel.isMpegNrAvailable();
596 case CHANNEL_XVCOLOR:
597 precond = projectorModel.isXvColorAvailable();
599 case CHANNEL_OVERSCAN:
600 precond = projectorModel.isOverscanAvailable();
602 case CHANNEL_PICTURE_POSITION:
603 precond = projectorModel.isPicturePositionAvailable();
605 case CHANNEL_LAMP_USE_TIME:
606 precond = requestValue;
612 if (isLinked(channel) && precond) {
613 state = UnDefType.UNDEF;
618 state = connector.getStatusPower().isOn() ? OnOffType.ON : OnOffType.OFF;
620 case CHANNEL_POWERSTATE:
621 state = new StringType(connector.getStatusPower().name());
624 state = new StringType(connector.getInput());
626 case CHANNEL_CALIBRATION_PRESET:
627 state = new StringType(connector.getCalibrationPreset());
629 case CHANNEL_CONTRAST:
630 state = new PercentType(connector.getContrast());
632 case CHANNEL_BRIGHTNESS:
633 state = new PercentType(connector.getBrightness());
636 state = new PercentType(connector.getColor());
639 state = new PercentType(connector.getHue());
641 case CHANNEL_SHARPNESS:
642 state = new PercentType(connector.getSharpness());
644 case CHANNEL_COLOR_TEMP:
645 state = new StringType(connector.getColorTemperature());
647 case CHANNEL_IRIS_MODE:
648 state = new StringType(connector.getIrisMode());
650 case CHANNEL_IRIS_MANUAL:
651 state = new PercentType(connector.getIrisManual());
653 case CHANNEL_IRIS_SENSITIVITY:
654 state = new StringType(connector.getIrisSensitivity());
656 case CHANNEL_LAMP_CONTROL:
657 state = new StringType(connector.getLampControl());
659 case CHANNEL_FILM_PROJECTION:
660 state = new StringType(connector.getFilmProjection());
662 case CHANNEL_MOTION_ENHANCER:
663 state = new StringType(connector.getMotionEnhancer());
665 case CHANNEL_CONTRAST_ENHANCER:
666 state = new StringType(connector.getContrastEnhancer());
668 case CHANNEL_FILM_MODE:
669 state = new StringType(connector.getFilmMode());
671 case CHANNEL_GAMMA_CORRECTION:
672 state = new StringType(connector.getGammaCorrection());
674 case CHANNEL_COLOR_SPACE:
675 state = new StringType(connector.getColorSpace());
678 state = new StringType(connector.getNr());
680 case CHANNEL_BLOCK_NR:
681 state = new StringType(connector.getBlockNr());
683 case CHANNEL_MOSQUITO_NR:
684 state = new StringType(connector.getMosquitoNr());
686 case CHANNEL_MPEG_NR:
687 state = new StringType(connector.getMpegNr());
689 case CHANNEL_XVCOLOR:
690 state = connector.getXvColor();
692 case CHANNEL_PICTURE_MUTING:
693 state = connector.getPictureMuting();
696 state = new StringType(connector.getAspect());
698 case CHANNEL_OVERSCAN:
699 state = connector.getOverscan();
701 case CHANNEL_PICTURE_POSITION:
702 state = new StringType(connector.getPicturePosition());
704 case CHANNEL_LAMP_USE_TIME:
705 state = new DecimalType(connector.getLampUseTime());
710 logger.debug("Refresh channel {} with value {}", channel, state);
711 } catch (SonyProjectorException e) {
712 logger.debug("Refresh channel {} failed: {}", channel, e.getMessage());
719 private void refreshChannel(String channel, boolean requestValue) {
720 updateChannelStateAndCache(channel, requestProjectorValue(channel, requestValue));
723 private void updateChannelStateAndCache(String channel, @Nullable State state) {
725 updateState(channel, state);
727 if (!cache.containsKey(channel)) {
728 cache.put(channel, () -> {
729 synchronized (commandLock) {
730 return requestProjectorValue(channel, true);
734 cache.putValue(channel, state);