--- /dev/null
+/**
+ * Copyright (c) 2010-2024 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.discovery;
+
+import static org.openhab.binding.sonyprojector.internal.SonyProjectorBindingConstants.THING_TYPE_ETHERNET;
+
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.sonyprojector.internal.configuration.SonyProjectorEthernetConfiguration;
+import org.openhab.core.config.discovery.DiscoveryResult;
+import org.openhab.core.config.discovery.DiscoveryResultBuilder;
+import org.openhab.core.config.discovery.sddp.SddpDevice;
+import org.openhab.core.config.discovery.sddp.SddpDiscoveryParticipant;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingTypeUID;
+import org.openhab.core.thing.ThingUID;
+import org.osgi.service.component.annotations.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Discovery Service for Sony Projectors that support SDDP.
+ *
+ * @author Laurent Garnier - Initial contribution
+ *
+ */
+@NonNullByDefault
+@Component(immediate = true)
+public class SonyProjectorDiscoveryParticipant implements SddpDiscoveryParticipant {
+ private final Logger logger = LoggerFactory.getLogger(SonyProjectorDiscoveryParticipant.class);
+
+ private static final String SONY = "SONY";
+ private static final String TYPE_PROJECTOR = "PROJECTOR";
+
+ @Override
+ public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
+ return Set.of(THING_TYPE_ETHERNET);
+ }
+
+ @Override
+ public @Nullable DiscoveryResult createResult(SddpDevice device) {
+ final ThingUID uid = getThingUID(device);
+ if (uid != null) {
+ final String label = device.manufacturer + " " + device.model;
+ final Map<String, Object> properties = Map.of("host", device.ipAddress, //
+ "port", SonyProjectorEthernetConfiguration.DEFAULT_PORT, //
+ "model", SonyProjectorEthernetConfiguration.MODEL_AUTO, //
+ Thing.PROPERTY_MAC_ADDRESS, device.macAddress);
+ logger.debug("Created a DiscoveryResult for device '{}' with UID '{}'", label, uid.getId());
+ return DiscoveryResultBuilder.create(uid).withProperties(properties)
+ .withRepresentationProperty(Thing.PROPERTY_MAC_ADDRESS).withLabel(label).build();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public @Nullable ThingUID getThingUID(SddpDevice device) {
+ if (device.manufacturer.toUpperCase(Locale.ENGLISH).contains(SONY)
+ && device.type.toUpperCase(Locale.ENGLISH).contains(TYPE_PROJECTOR) && !device.macAddress.isBlank()
+ && !device.ipAddress.isBlank()) {
+
+ logger.debug("Sony projector with mac {} found at {}", device.macAddress, device.ipAddress);
+ return new ThingUID(THING_TYPE_ETHERNET, device.macAddress);
+ }
+ return null;
+ }
+}
package org.openhab.binding.sonyprojector.internal.handler;
import static org.openhab.binding.sonyprojector.internal.SonyProjectorBindingConstants.*;
+import static org.openhab.binding.sonyprojector.internal.configuration.SonyProjectorEthernetConfiguration.MODEL_AUTO;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@NonNullByDefault
public class SonyProjectorHandler extends BaseThingHandler {
- private static final SonyProjectorModel DEFAULT_MODEL = SonyProjectorModel.VW520;
+ public static final SonyProjectorModel DEFAULT_MODEL = SonyProjectorModel.VW528;
private static final long POLLING_INTERVAL = TimeUnit.SECONDS.toSeconds(15);
private final Logger logger = LoggerFactory.getLogger(SonyProjectorHandler.class);
private @Nullable ScheduledFuture<?> refreshJob;
+ private boolean identifyMac;
private boolean identifyProjector;
private SonyProjectorModel projectorModel = DEFAULT_MODEL;
private SonyProjectorConnector connector = new SonyProjectorSdcpSimuConnector(DEFAULT_MODEL);
logger.debug("Ethernet config port {}", config.port);
logger.debug("Ethernet config model {}", configModel);
logger.debug("Ethernet config community {}", config.community);
- if (config.host == null || config.host.isEmpty()) {
+ if (config.host.isBlank()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"@text/offline.config-error-unknown-host");
- } else if (configModel == null || configModel.isEmpty()) {
+ } else if (config.port <= 0) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
+ "@text/offline.config-error-invalid-port");
+ } else if (configModel.isBlank()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"@text/offline.config-error-unknown-model");
} else {
connector = simu ? new SonyProjectorSdcpSimuConnector(DEFAULT_MODEL)
: new SonyProjectorSdcpConnector(config.host, config.port, config.community, DEFAULT_MODEL);
- identifyProjector = "AUTO".equals(configModel);
- projectorModel = switchToModel("AUTO".equals(configModel) ? null : configModel, true);
+ identifyMac = getThing().getProperties().get(Thing.PROPERTY_MAC_ADDRESS) == null;
+ identifyProjector = MODEL_AUTO.equals(configModel);
+ projectorModel = switchToModel(identifyProjector ? null : configModel, true);
updateStatus(ThingStatus.UNKNOWN);
}
String configModel = config.model;
logger.debug("Serial config port {}", config.port);
logger.debug("Serial config model {}", configModel);
- if (config.port == null || config.port.isEmpty()) {
+ if (config.port.isBlank()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"@text/offline.config-error-unknown-port");
} else if (config.port.toLowerCase().startsWith("rfc2217")) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"@text/offline.config-error-invalid-thing-type");
- } else if (configModel == null || configModel.isEmpty()) {
+ } else if (configModel.isBlank()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"@text/offline.config-error-unknown-model");
} else {
connector = simu ? new SonyProjectorSerialSimuConnector(serialPortManager, DEFAULT_MODEL)
: new SonyProjectorSerialConnector(serialPortManager, config.port, DEFAULT_MODEL);
+ identifyMac = false;
identifyProjector = false;
projectorModel = switchToModel(configModel, true);
logger.debug("Serial over IP config host {}", config.host);
logger.debug("Serial over IP config port {}", config.port);
logger.debug("Serial over IP config model {}", configModel);
- if (config.host == null || config.host.isEmpty()) {
+ if (config.host.isBlank()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"@text/offline.config-error-unknown-host");
- } else if (config.port == null) {
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
- "@text/offline.config-error-unknown-port");
} else if (config.port <= 0) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"@text/offline.config-error-invalid-port");
- } else if (configModel == null || configModel.isEmpty()) {
+ } else if (configModel.isBlank()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"@text/offline.config-error-unknown-model");
} else {
connector = simu ? new SonyProjectorSerialSimuConnector(serialPortManager, DEFAULT_MODEL)
: new SonyProjectorSerialOverIpConnector(serialPortManager, config.host, config.port,
DEFAULT_MODEL);
+ identifyMac = false;
identifyProjector = false;
projectorModel = switchToModel(configModel, true);
boolean isOn = refreshPowerState();
refreshModel();
+ refreshMacAddress();
refreshChannel(CHANNEL_INPUT, isOn);
refreshChannel(CHANNEL_CALIBRATION_PRESET, isOn);
refreshChannel(CHANNEL_CONTRAST, isOn);
return model;
}
+ private void refreshMacAddress() {
+ if (identifyMac && getThing().getThingTypeUID().equals(THING_TYPE_ETHERNET)) {
+ try {
+ String mac = ((SonyProjectorSdcpConnector) connector).getMacAddress();
+ logger.debug("getMacAddress returned {}", mac);
+ getThing().setProperty(Thing.PROPERTY_MAC_ADDRESS, mac);
+ identifyMac = false;
+ } catch (SonyProjectorException e) {
+ logger.debug("getMacAddress failed: {}", e.getMessage());
+ }
+ }
+ }
+
private boolean refreshPowerState() {
boolean on = false;
State state = UnDefType.UNDEF;