mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[sonyprojector] Add discovery through SDDP (#16849)
Only applicable to projector models having a network connector Signed-off-by: Laurent Garnier <lg.hc@free.fr> Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
parent
30860884e3
commit
ff7ebd7ac4
@ -94,8 +94,8 @@ This binding supports the following thing types:
|
||||
|
||||
## Discovery
|
||||
|
||||
Discovery is not supported at the moment.
|
||||
You have to add all things manually.
|
||||
If the projector is connected via Ethernet and the 'Start SDDP Service' option is present and enabled in the projector Advanced Settings->Service page, the Thing using Ethernet connection and PJ Talk will be discovered automatically.
|
||||
Serial or Serial over IP connections must be configured manually.
|
||||
|
||||
## Binding Configuration
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
<feature name="openhab-binding-sonyprojector" description="Sony Projector Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<feature>openhab-transport-serial</feature>
|
||||
<feature>openhab-core-config-discovery-sddp</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.sonyprojector/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
|
@ -143,6 +143,9 @@ public enum SonyProjectorItem {
|
||||
SERIAL_NUMBER("Serial Number", new byte[] { (byte) 0x80, 0x02 }),
|
||||
INSTALLATION_LOCATION("Installation Location", new byte[] { (byte) 0x80, 0x03 }),
|
||||
|
||||
MAC_ADDRESS("MAC Address", new byte[] { (byte) 0x90, 0x00 }),
|
||||
IP_ADDRESS("IP Address", new byte[] { (byte) 0x90, 0x01 }),
|
||||
|
||||
MENU("Menu", null, new byte[] { 0x17, 0x29 }),
|
||||
UP("Cursor UP", null, new byte[] { 0x17, 0x35 }),
|
||||
DOWN("Cursor DOWN", null, new byte[] { 0x17, 0x36 }),
|
||||
|
@ -311,4 +311,15 @@ public class SonyProjectorSdcpConnector extends SonyProjectorConnector {
|
||||
public String getModelName() throws SonyProjectorException {
|
||||
return new String(getSetting(SonyProjectorItem.MODEL_NAME), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the MAC address
|
||||
*
|
||||
* @return the MAC address
|
||||
*
|
||||
* @throws SonyProjectorException in case of any problem
|
||||
*/
|
||||
public String getMacAddress() throws SonyProjectorException {
|
||||
return new String(getSetting(SonyProjectorItem.MAC_ADDRESS), StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
package org.openhab.binding.sonyprojector.internal.configuration;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The {@link SonyProjectorEthernetConfiguration} class contains fields mapping thing configuration parameters.
|
||||
@ -23,9 +22,12 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SonyProjectorEthernetConfiguration {
|
||||
public static final int DEFAULT_PORT = 53484;
|
||||
private static final String DEFAULT_COMMUNITY = "SONY";
|
||||
public static final String MODEL_AUTO = "AUTO";
|
||||
|
||||
public @NonNullByDefault({}) String host;
|
||||
public @Nullable Integer port;
|
||||
public @Nullable String community;
|
||||
public @Nullable String model;
|
||||
public String host = "";
|
||||
public int port = DEFAULT_PORT;
|
||||
public String community = DEFAULT_COMMUNITY;
|
||||
public String model = MODEL_AUTO;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
package org.openhab.binding.sonyprojector.internal.configuration;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.sonyprojector.internal.handler.SonyProjectorHandler;
|
||||
|
||||
/**
|
||||
* The {@link SonyProjectorSerialConfiguration} class contains fields mapping thing configuration parameters.
|
||||
@ -21,7 +22,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SonyProjectorSerialConfiguration {
|
||||
|
||||
public @NonNullByDefault({}) String port;
|
||||
public @NonNullByDefault({}) String model;
|
||||
public String port = "";
|
||||
public String model = SonyProjectorHandler.DEFAULT_MODEL.getName();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
package org.openhab.binding.sonyprojector.internal.configuration;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.sonyprojector.internal.handler.SonyProjectorHandler;
|
||||
|
||||
/**
|
||||
* The {@link SonyProjectorSerialOverIpConfiguration} class contains fields mapping thing configuration parameters.
|
||||
@ -21,8 +22,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SonyProjectorSerialOverIpConfiguration {
|
||||
|
||||
public @NonNullByDefault({}) String host;
|
||||
public @NonNullByDefault({}) Integer port;
|
||||
public @NonNullByDefault({}) String model;
|
||||
public String host = "";
|
||||
public int port;
|
||||
public String model = SonyProjectorHandler.DEFAULT_MODEL.getName();
|
||||
}
|
||||
|
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
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;
|
||||
@ -67,7 +68,7 @@ import org.slf4j.LoggerFactory;
|
||||
@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);
|
||||
@ -83,6 +84,7 @@ public class SonyProjectorHandler extends BaseThingHandler {
|
||||
|
||||
private @Nullable ScheduledFuture<?> refreshJob;
|
||||
|
||||
private boolean identifyMac;
|
||||
private boolean identifyProjector;
|
||||
private SonyProjectorModel projectorModel = DEFAULT_MODEL;
|
||||
private SonyProjectorConnector connector = new SonyProjectorSdcpSimuConnector(DEFAULT_MODEL);
|
||||
@ -321,10 +323,13 @@ public class SonyProjectorHandler extends BaseThingHandler {
|
||||
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 {
|
||||
@ -332,8 +337,9 @@ public class SonyProjectorHandler extends BaseThingHandler {
|
||||
|
||||
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);
|
||||
}
|
||||
@ -342,13 +348,13 @@ public class SonyProjectorHandler extends BaseThingHandler {
|
||||
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 {
|
||||
@ -356,6 +362,7 @@ public class SonyProjectorHandler extends BaseThingHandler {
|
||||
|
||||
connector = simu ? new SonyProjectorSerialSimuConnector(serialPortManager, DEFAULT_MODEL)
|
||||
: new SonyProjectorSerialConnector(serialPortManager, config.port, DEFAULT_MODEL);
|
||||
identifyMac = false;
|
||||
identifyProjector = false;
|
||||
projectorModel = switchToModel(configModel, true);
|
||||
|
||||
@ -367,16 +374,13 @@ public class SonyProjectorHandler extends BaseThingHandler {
|
||||
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 {
|
||||
@ -385,6 +389,7 @@ public class SonyProjectorHandler extends BaseThingHandler {
|
||||
connector = simu ? new SonyProjectorSerialSimuConnector(serialPortManager, DEFAULT_MODEL)
|
||||
: new SonyProjectorSerialOverIpConnector(serialPortManager, config.host, config.port,
|
||||
DEFAULT_MODEL);
|
||||
identifyMac = false;
|
||||
identifyProjector = false;
|
||||
projectorModel = switchToModel(configModel, true);
|
||||
|
||||
@ -432,6 +437,7 @@ public class SonyProjectorHandler extends BaseThingHandler {
|
||||
|
||||
boolean isOn = refreshPowerState();
|
||||
refreshModel();
|
||||
refreshMacAddress();
|
||||
refreshChannel(CHANNEL_INPUT, isOn);
|
||||
refreshChannel(CHANNEL_CALIBRATION_PRESET, isOn);
|
||||
refreshChannel(CHANNEL_CONTRAST, isOn);
|
||||
@ -537,6 +543,19 @@ public class SonyProjectorHandler extends BaseThingHandler {
|
||||
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;
|
||||
|
@ -12,9 +12,13 @@
|
||||
<discovery-method>
|
||||
<service-type>sddp</service-type>
|
||||
<match-properties>
|
||||
<match-property>
|
||||
<name>manufacturer</name>
|
||||
<regex>(?i).*sony.*</regex>
|
||||
</match-property>
|
||||
<match-property>
|
||||
<name>type</name>
|
||||
<regex>(?i)sony:projector.*</regex>
|
||||
<regex>(?i).*projector.*</regex>
|
||||
</match-property>
|
||||
</match-properties>
|
||||
</discovery-method>
|
||||
|
Loading…
Reference in New Issue
Block a user