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.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.io.transport.serial.SerialPortManager;
37 import org.openhab.core.library.types.DecimalType;
38 import org.openhab.core.library.types.OnOffType;
39 import org.openhab.core.library.types.PercentType;
40 import org.openhab.core.library.types.StringType;
41 import org.openhab.core.thing.ChannelUID;
42 import org.openhab.core.thing.Thing;
43 import org.openhab.core.thing.ThingStatus;
44 import org.openhab.core.thing.ThingStatusDetail;
45 import org.openhab.core.thing.binding.BaseThingHandler;
46 import org.openhab.core.types.Command;
47 import org.openhab.core.types.RefreshType;
48 import org.openhab.core.types.State;
49 import org.openhab.core.types.UnDefType;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
54 * The {@link SonyProjectorHandler} is responsible for handling commands, which are
55 * sent to one of the channels.
57 * @author Markus Wehrle - Initial contribution
58 * @author Laurent Garnier - Refactoring, poll thread for regular channels updates, new serial thing type, new channels
61 public class SonyProjectorHandler extends BaseThingHandler {
63 private final Logger logger = LoggerFactory.getLogger(SonyProjectorHandler.class);
65 private static final SonyProjectorModel DEFAULT_MODEL = SonyProjectorModel.VW520;
66 private static final long POLLING_INTERVAL = TimeUnit.SECONDS.toSeconds(15);
68 private @Nullable ScheduledFuture<?> refreshJob;
70 private boolean identifyProjector;
71 private SonyProjectorModel projectorModel = DEFAULT_MODEL;
72 private SonyProjectorConnector connector = new SonyProjectorSdcpSimuConnector(DEFAULT_MODEL);
74 private SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider;
75 private SerialPortManager serialPortManager;
79 private final Object commandLock = new Object();
81 private final ExpiringCacheMap<String, State> cache;
83 public SonyProjectorHandler(Thing thing, SonyProjectorStateDescriptionOptionProvider stateDescriptionProvider,
84 SerialPortManager serialPortManager) {
86 this.stateDescriptionProvider = stateDescriptionProvider;
87 this.serialPortManager = serialPortManager;
88 this.cache = new ExpiringCacheMap<>(TimeUnit.SECONDS.toMillis(POLLING_INTERVAL));
92 public void handleCommand(ChannelUID channelUID, Command command) {
93 String channel = channelUID.getId();
94 if (command instanceof RefreshType) {
95 State state = cache.get(channel);
97 updateState(channel, state);
102 synchronized (commandLock) {
105 } catch (SonyProjectorException e) {
106 logger.debug("Command {} from channel {} failed: {}", command, channel, e.getMessage());
107 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
113 if (command == OnOffType.ON) {
115 } else if (command == OnOffType.OFF) {
116 connector.powerOff();
118 throw new SonyProjectorException("Invalid command value");
122 connector.setInput(command.toString());
124 case CHANNEL_CALIBRATION_PRESET:
125 connector.setCalibrationPreset(command.toString());
126 refreshChannel(CHANNEL_CONTRAST, true);
127 refreshChannel(CHANNEL_BRIGHTNESS, true);
128 refreshChannel(CHANNEL_COLOR, true);
129 refreshChannel(CHANNEL_HUE, true);
130 refreshChannel(CHANNEL_SHARPNESS, true);
131 refreshChannel(CHANNEL_COLOR_TEMP, true);
132 refreshChannel(CHANNEL_IRIS_MODE, true);
133 refreshChannel(CHANNEL_IRIS_MANUAL, true);
134 refreshChannel(CHANNEL_IRIS_SENSITIVITY, true);
135 refreshChannel(CHANNEL_LAMP_CONTROL, true);
136 refreshChannel(CHANNEL_FILM_PROJECTION, true);
137 refreshChannel(CHANNEL_MOTION_ENHANCER, true);
138 refreshChannel(CHANNEL_CONTRAST_ENHANCER, true);
139 refreshChannel(CHANNEL_FILM_MODE, true);
140 refreshChannel(CHANNEL_GAMMA_CORRECTION, true);
141 refreshChannel(CHANNEL_COLOR_SPACE, true);
142 refreshChannel(CHANNEL_NR, true);
143 refreshChannel(CHANNEL_BLOCK_NR, true);
144 refreshChannel(CHANNEL_MOSQUITO_NR, true);
145 refreshChannel(CHANNEL_MPEG_NR, true);
146 refreshChannel(CHANNEL_XVCOLOR, true);
148 case CHANNEL_CONTRAST:
149 if (command instanceof DecimalType) {
150 connector.setContrast(((DecimalType) command).intValue());
151 } else if (command instanceof PercentType) {
152 connector.setContrast(((PercentType) command).intValue());
154 throw new SonyProjectorException("Invalid command value");
157 case CHANNEL_BRIGHTNESS:
158 if (command instanceof DecimalType) {
159 connector.setBrightness(((DecimalType) command).intValue());
160 } else if (command instanceof PercentType) {
161 connector.setBrightness(((PercentType) command).intValue());
163 throw new SonyProjectorException("Invalid command value");
167 if (command instanceof DecimalType) {
168 connector.setColor(((DecimalType) command).intValue());
169 } else if (command instanceof PercentType) {
170 connector.setColor(((PercentType) command).intValue());
172 throw new SonyProjectorException("Invalid command value");
176 if (command instanceof DecimalType) {
177 connector.setHue(((DecimalType) command).intValue());
178 } else if (command instanceof PercentType) {
179 connector.setHue(((PercentType) command).intValue());
181 throw new SonyProjectorException("Invalid command value");
184 case CHANNEL_SHARPNESS:
185 if (command instanceof DecimalType) {
186 connector.setSharpness(((DecimalType) command).intValue());
187 } else if (command instanceof PercentType) {
188 connector.setSharpness(((PercentType) command).intValue());
190 throw new SonyProjectorException("Invalid command value");
193 case CHANNEL_COLOR_TEMP:
194 connector.setColorTemperature(command.toString());
196 case CHANNEL_IRIS_MODE:
197 connector.setIrisMode(command.toString());
198 refreshChannel(CHANNEL_IRIS_MANUAL, true);
200 case CHANNEL_IRIS_MANUAL:
201 if (command instanceof DecimalType) {
202 connector.setIrisManual(((DecimalType) command).intValue());
203 } else if (command instanceof PercentType) {
204 connector.setIrisManual(((PercentType) command).intValue());
206 throw new SonyProjectorException("Invalid command value");
209 case CHANNEL_IRIS_SENSITIVITY:
210 connector.setIrisSensitivity(command.toString());
212 case CHANNEL_LAMP_CONTROL:
213 connector.setLampControl(command.toString());
215 case CHANNEL_FILM_PROJECTION:
216 connector.setFilmProjection(command.toString());
218 case CHANNEL_MOTION_ENHANCER:
219 connector.setMotionEnhancer(command.toString());
221 case CHANNEL_CONTRAST_ENHANCER:
222 connector.setContrastEnhancer(command.toString());
224 case CHANNEL_FILM_MODE:
225 connector.setFilmMode(command.toString());
227 case CHANNEL_GAMMA_CORRECTION:
228 connector.setGammaCorrection(command.toString());
230 case CHANNEL_COLOR_SPACE:
231 connector.setColorSpace(command.toString());
234 connector.setNr(command.toString());
236 case CHANNEL_BLOCK_NR:
237 connector.setBlockNr(command.toString());
239 case CHANNEL_MOSQUITO_NR:
240 connector.setMosquitoNr(command.toString());
242 case CHANNEL_MPEG_NR:
243 connector.setMpegNr(command.toString());
245 case CHANNEL_XVCOLOR:
246 if (command == OnOffType.ON) {
247 connector.enableXvColor();
248 refreshChannel(CHANNEL_GAMMA_CORRECTION, true);
249 } else if (command == OnOffType.OFF) {
250 connector.disableXvColor();
251 refreshChannel(CHANNEL_GAMMA_CORRECTION, true);
253 throw new SonyProjectorException("Invalid command value");
256 case CHANNEL_PICTURE_MUTING:
257 if (command == OnOffType.ON) {
258 connector.mutePicture();
259 } else if (command == OnOffType.OFF) {
260 connector.unmutePicture();
262 throw new SonyProjectorException("Invalid command value");
266 connector.setAspect(command.toString());
268 case CHANNEL_OVERSCAN:
269 if (command == OnOffType.ON) {
270 connector.enableOverscan();
271 } else if (command == OnOffType.OFF) {
272 connector.disableOverscan();
274 throw new SonyProjectorException("Invalid command value");
277 case CHANNEL_PICTURE_POSITION:
278 connector.setPicturePosition(command.toString());
281 throw new SonyProjectorException("Unexpected command");
283 logger.debug("Command {} from channel {} succeeded", command, channel);
284 } catch (SonyProjectorException e) {
285 logger.debug("Command {} from channel {} failed: {}", command, channel, e.getMessage());
286 refreshChannel(channel, true);
293 public void initialize() {
294 logger.debug("Start initializing handler for thing {}", getThing().getUID());
296 boolean configOk = false;
298 if (getThing().getThingTypeUID().equals(THING_TYPE_ETHERNET)) {
299 SonyProjectorEthernetConfiguration config = getConfigAs(SonyProjectorEthernetConfiguration.class);
300 String configModel = config.model;
301 logger.debug("Ethernet config host {}", config.host);
302 logger.debug("Ethernet config port {}", config.port);
303 logger.debug("Ethernet config model {}", configModel);
304 logger.debug("Ethernet config community {}", config.community);
305 if (config.host == null || config.host.isEmpty()) {
306 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
307 "@text/offline.config-error-unknown-host");
308 } else if (configModel == null || configModel.isEmpty()) {
309 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
310 "@text/offline.config-error-unknown-model");
314 connector = simu ? new SonyProjectorSdcpSimuConnector(DEFAULT_MODEL)
315 : new SonyProjectorSdcpConnector(config.host, config.port, config.community, DEFAULT_MODEL);
316 identifyProjector = "AUTO".equals(configModel);
317 projectorModel = switchToModel("AUTO".equals(configModel) ? null : configModel, true);
319 updateStatus(ThingStatus.UNKNOWN);
321 } else if (getThing().getThingTypeUID().equals(THING_TYPE_SERIAL)) {
322 SonyProjectorSerialConfiguration config = getConfigAs(SonyProjectorSerialConfiguration.class);
323 String configModel = config.model;
324 logger.debug("Serial config port {}", config.port);
325 logger.debug("Serial config model {}", configModel);
326 if (config.port == null || config.port.isEmpty()) {
327 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
328 "@text/offline.config-error-unknown-port");
329 } else if (config.port.toLowerCase().startsWith("rfc2217")) {
330 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
331 "@text/offline.config-error-invalid-thing-type");
332 } else if (configModel == null || configModel.isEmpty()) {
333 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
334 "@text/offline.config-error-unknown-model");
338 connector = simu ? new SonyProjectorSerialSimuConnector(serialPortManager, DEFAULT_MODEL)
339 : new SonyProjectorSerialConnector(serialPortManager, config.port, DEFAULT_MODEL);
340 identifyProjector = false;
341 projectorModel = switchToModel(configModel, true);
343 updateStatus(ThingStatus.UNKNOWN);
345 } else if (getThing().getThingTypeUID().equals(THING_TYPE_SERIAL_OVER_IP)) {
346 SonyProjectorSerialOverIpConfiguration config = getConfigAs(SonyProjectorSerialOverIpConfiguration.class);
347 String configModel = config.model;
348 logger.debug("Serial over IP config host {}", config.host);
349 logger.debug("Serial over IP config port {}", config.port);
350 logger.debug("Serial over IP config model {}", configModel);
351 if (config.host == null || config.host.isEmpty()) {
352 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
353 "@text/offline.config-error-unknown-host");
354 } else if (config.port == null) {
355 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
356 "@text/offline.config-error-unknown-port");
357 } else if (config.port <= 0) {
358 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
359 "@text/offline.config-error-invalid-port");
360 } else if (configModel == null || configModel.isEmpty()) {
361 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
362 "@text/offline.config-error-unknown-model");
366 connector = simu ? new SonyProjectorSerialSimuConnector(serialPortManager, DEFAULT_MODEL)
367 : new SonyProjectorSerialOverIpConnector(serialPortManager, config.host, config.port,
369 identifyProjector = false;
370 projectorModel = switchToModel(configModel, true);
372 updateStatus(ThingStatus.UNKNOWN);
377 connector = new SonyProjectorSdcpSimuConnector(DEFAULT_MODEL);
379 ScheduledFuture<?> refreshJob = this.refreshJob;
380 if (refreshJob == null || refreshJob.isCancelled()) {
381 this.refreshJob = scheduler.scheduleWithFixedDelay(() -> {
383 }, 1, POLLING_INTERVAL, TimeUnit.SECONDS);
387 logger.debug("Finished initializing!");
391 public void dispose() {
392 logger.debug("Disposing handler for thing {}", getThing().getUID());
393 ScheduledFuture<?> refreshJob = this.refreshJob;
394 if (refreshJob != null && !refreshJob.isCancelled()) {
395 refreshJob.cancel(true);
396 this.refreshJob = null;
402 private void pollProjector() {
403 synchronized (commandLock) {
404 logger.debug("Polling the projector to refresh the channels...");
408 } catch (SonyProjectorException e) {
409 logger.debug("Poll projector failed: {}", e.getMessage());
410 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
414 boolean isOn = refreshPowerState();
416 refreshChannel(CHANNEL_INPUT, isOn);
417 refreshChannel(CHANNEL_CALIBRATION_PRESET, isOn);
418 refreshChannel(CHANNEL_CONTRAST, isOn);
419 refreshChannel(CHANNEL_BRIGHTNESS, isOn);
420 refreshChannel(CHANNEL_COLOR, isOn);
421 refreshChannel(CHANNEL_HUE, isOn);
422 refreshChannel(CHANNEL_SHARPNESS, isOn);
423 refreshChannel(CHANNEL_COLOR_TEMP, isOn);
424 refreshChannel(CHANNEL_IRIS_MODE, isOn);
425 refreshChannel(CHANNEL_IRIS_MANUAL, isOn);
426 refreshChannel(CHANNEL_IRIS_SENSITIVITY, isOn);
427 refreshChannel(CHANNEL_LAMP_CONTROL, isOn);
428 refreshChannel(CHANNEL_FILM_PROJECTION, isOn);
429 refreshChannel(CHANNEL_MOTION_ENHANCER, isOn);
430 refreshChannel(CHANNEL_CONTRAST_ENHANCER, isOn);
431 refreshChannel(CHANNEL_FILM_MODE, isOn);
432 refreshChannel(CHANNEL_GAMMA_CORRECTION, isOn);
433 refreshChannel(CHANNEL_COLOR_SPACE, isOn);
434 refreshChannel(CHANNEL_NR, isOn);
435 refreshChannel(CHANNEL_BLOCK_NR, isOn);
436 refreshChannel(CHANNEL_MOSQUITO_NR, isOn);
437 refreshChannel(CHANNEL_MPEG_NR, isOn);
438 refreshChannel(CHANNEL_XVCOLOR, isOn);
439 refreshChannel(CHANNEL_PICTURE_MUTING, isOn);
440 refreshChannel(CHANNEL_ASPECT, isOn);
441 refreshChannel(CHANNEL_OVERSCAN, isOn);
442 refreshChannel(CHANNEL_PICTURE_POSITION, isOn);
443 refreshChannel(CHANNEL_LAMP_USE_TIME, isOn);
447 updateStatus(ThingStatus.ONLINE);
449 logger.debug("End of the polling thread");
453 private void refreshModel() {
454 if (identifyProjector && getThing().getThingTypeUID().equals(THING_TYPE_ETHERNET)) {
456 String modelName = ((SonyProjectorSdcpConnector) connector).getModelName();
457 logger.debug("getModelName returned {}", modelName);
458 identifyProjector = false;
459 switchToModel(modelName, false);
460 } catch (SonyProjectorException e) {
461 logger.debug("getModelName failed: {}", e.getMessage());
466 private SonyProjectorModel switchToModel(@Nullable String modelName, boolean force) {
467 SonyProjectorModel model = DEFAULT_MODEL;
468 if (modelName != null && !modelName.isEmpty()) {
470 model = SonyProjectorModel.getFromName(modelName, false);
471 logger.debug("Model found: {}", model.getName());
472 } catch (SonyProjectorException e) {
473 logger.info("Model {} is unknow; consider {} by default", modelName, DEFAULT_MODEL.getName());
476 if (force || !model.getName().equals(projectorModel.getName())) {
477 connector.setModel(model);
478 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_INPUT),
479 model.getInputStateOptions());
480 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_CALIBRATION_PRESET),
481 model.getCalibrPresetStateOptions());
482 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_COLOR_TEMP),
483 model.getColorTempStateOptions());
484 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_IRIS_MODE),
485 model.getIrisModeStateOptions());
486 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_IRIS_SENSITIVITY),
487 model.getIrisSensitivityStateOptions());
488 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_LAMP_CONTROL),
489 model.getLampControlStateOptions());
490 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_FILM_PROJECTION),
491 model.getFilmProjectionStateOptions());
492 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_MOTION_ENHANCER),
493 model.getMotionEnhancerStateOptions());
494 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_CONTRAST_ENHANCER),
495 model.getContrastEnhancerStateOptions());
496 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_FILM_MODE),
497 model.getFilmModeStateOptions());
498 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_GAMMA_CORRECTION),
499 model.getGammaCorrectionStateOptions());
500 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_COLOR_SPACE),
501 model.getColorSpaceStateOptions());
502 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_NR),
503 model.getNrStateOptions());
504 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_BLOCK_NR),
505 model.getBlockNrStateOptions());
506 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_MOSQUITO_NR),
507 model.getMosquitoNrStateOptions());
508 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_MPEG_NR),
509 model.getMpegNrStateOptions());
510 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_ASPECT),
511 model.getAspectStateOptions());
512 stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_PICTURE_POSITION),
513 model.getPicturePositionStateOptions());
518 private boolean refreshPowerState() {
520 State state = UnDefType.UNDEF;
522 SonyProjectorStatusPower value = connector.getStatusPower();
523 logger.debug("Get Status Power returned {}", value);
525 state = new StringType(value.name());
526 } catch (SonyProjectorException e) {
527 logger.debug("Get Status Power failed: {}", e.getMessage());
529 updateChannelStateAndCache(CHANNEL_POWER, on ? OnOffType.ON : OnOffType.OFF);
530 updateChannelStateAndCache(CHANNEL_POWERSTATE, state);
534 private @Nullable State requestProjectorValue(String channel, boolean requestValue) {
539 case CHANNEL_POWERSTATE:
541 case CHANNEL_CALIBRATION_PRESET:
542 case CHANNEL_CONTRAST:
543 case CHANNEL_BRIGHTNESS:
546 case CHANNEL_SHARPNESS:
547 case CHANNEL_COLOR_TEMP:
548 case CHANNEL_CONTRAST_ENHANCER:
549 case CHANNEL_GAMMA_CORRECTION:
550 case CHANNEL_COLOR_SPACE:
552 case CHANNEL_PICTURE_MUTING:
556 case CHANNEL_IRIS_MODE:
557 precond = projectorModel.isIrisModeAvailable();
559 case CHANNEL_IRIS_MANUAL:
560 precond = projectorModel.isIrisManualAvailable();
562 case CHANNEL_IRIS_SENSITIVITY:
563 precond = projectorModel.isIrisSensitivityAvailable();
565 case CHANNEL_LAMP_CONTROL:
566 precond = projectorModel.isLampControlAvailable();
568 case CHANNEL_FILM_PROJECTION:
569 precond = projectorModel.isFilmProjectionAvailable();
571 case CHANNEL_MOTION_ENHANCER:
572 precond = projectorModel.isMotionEnhancerAvailable();
574 case CHANNEL_FILM_MODE:
575 precond = projectorModel.isFilmModeAvailable();
577 case CHANNEL_BLOCK_NR:
578 precond = projectorModel.isBlockNrAvailable();
580 case CHANNEL_MOSQUITO_NR:
581 precond = projectorModel.isMosquitoNrAvailable();
583 case CHANNEL_MPEG_NR:
584 precond = projectorModel.isMpegNrAvailable();
586 case CHANNEL_XVCOLOR:
587 precond = projectorModel.isXvColorAvailable();
589 case CHANNEL_OVERSCAN:
590 precond = projectorModel.isOverscanAvailable();
592 case CHANNEL_PICTURE_POSITION:
593 precond = projectorModel.isPicturePositionAvailable();
595 case CHANNEL_LAMP_USE_TIME:
596 precond = requestValue;
602 if (isLinked(channel) && precond) {
603 state = UnDefType.UNDEF;
608 state = connector.getStatusPower().isOn() ? OnOffType.ON : OnOffType.OFF;
610 case CHANNEL_POWERSTATE:
611 state = new StringType(connector.getStatusPower().name());
614 state = new StringType(connector.getInput());
616 case CHANNEL_CALIBRATION_PRESET:
617 state = new StringType(connector.getCalibrationPreset());
619 case CHANNEL_CONTRAST:
620 state = new PercentType(connector.getContrast());
622 case CHANNEL_BRIGHTNESS:
623 state = new PercentType(connector.getBrightness());
626 state = new PercentType(connector.getColor());
629 state = new PercentType(connector.getHue());
631 case CHANNEL_SHARPNESS:
632 state = new PercentType(connector.getSharpness());
634 case CHANNEL_COLOR_TEMP:
635 state = new StringType(connector.getColorTemperature());
637 case CHANNEL_IRIS_MODE:
638 state = new StringType(connector.getIrisMode());
640 case CHANNEL_IRIS_MANUAL:
641 state = new PercentType(connector.getIrisManual());
643 case CHANNEL_IRIS_SENSITIVITY:
644 state = new StringType(connector.getIrisSensitivity());
646 case CHANNEL_LAMP_CONTROL:
647 state = new StringType(connector.getLampControl());
649 case CHANNEL_FILM_PROJECTION:
650 state = new StringType(connector.getFilmProjection());
652 case CHANNEL_MOTION_ENHANCER:
653 state = new StringType(connector.getMotionEnhancer());
655 case CHANNEL_CONTRAST_ENHANCER:
656 state = new StringType(connector.getContrastEnhancer());
658 case CHANNEL_FILM_MODE:
659 state = new StringType(connector.getFilmMode());
661 case CHANNEL_GAMMA_CORRECTION:
662 state = new StringType(connector.getGammaCorrection());
664 case CHANNEL_COLOR_SPACE:
665 state = new StringType(connector.getColorSpace());
668 state = new StringType(connector.getNr());
670 case CHANNEL_BLOCK_NR:
671 state = new StringType(connector.getBlockNr());
673 case CHANNEL_MOSQUITO_NR:
674 state = new StringType(connector.getMosquitoNr());
676 case CHANNEL_MPEG_NR:
677 state = new StringType(connector.getMpegNr());
679 case CHANNEL_XVCOLOR:
680 state = connector.getXvColor();
682 case CHANNEL_PICTURE_MUTING:
683 state = connector.getPictureMuting();
686 state = new StringType(connector.getAspect());
688 case CHANNEL_OVERSCAN:
689 state = connector.getOverscan();
691 case CHANNEL_PICTURE_POSITION:
692 state = new StringType(connector.getPicturePosition());
694 case CHANNEL_LAMP_USE_TIME:
695 state = new DecimalType(connector.getLampUseTime());
700 logger.debug("Refresh channel {} with value {}", channel, state);
701 } catch (SonyProjectorException e) {
702 logger.debug("Refresh channel {} failed: {}", channel, e.getMessage());
709 private void refreshChannel(String channel, boolean requestValue) {
710 updateChannelStateAndCache(channel, requestProjectorValue(channel, requestValue));
713 private void updateChannelStateAndCache(String channel, @Nullable State state) {
715 updateState(channel, state);
717 if (!cache.containsKey(channel)) {
718 cache.put(channel, () -> {
719 synchronized (commandLock) {
720 return requestProjectorValue(channel, true);
724 cache.putValue(channel, state);