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.powermax.internal.discovery;
15 import java.util.Date;
16 import java.util.HashMap;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.powermax.internal.PowermaxBindingConstants;
22 import org.openhab.binding.powermax.internal.config.PowermaxX10Configuration;
23 import org.openhab.binding.powermax.internal.config.PowermaxZoneConfiguration;
24 import org.openhab.binding.powermax.internal.handler.PowermaxBridgeHandler;
25 import org.openhab.binding.powermax.internal.handler.PowermaxThingHandler;
26 import org.openhab.binding.powermax.internal.state.PowermaxPanelSettings;
27 import org.openhab.binding.powermax.internal.state.PowermaxPanelSettingsListener;
28 import org.openhab.binding.powermax.internal.state.PowermaxX10Settings;
29 import org.openhab.binding.powermax.internal.state.PowermaxZoneSettings;
30 import org.openhab.core.config.discovery.AbstractDiscoveryService;
31 import org.openhab.core.config.discovery.DiscoveryResult;
32 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
33 import org.openhab.core.thing.Thing;
34 import org.openhab.core.thing.ThingUID;
35 import org.openhab.core.thing.binding.ThingHandler;
36 import org.openhab.core.thing.binding.ThingHandlerService;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
41 * The {@link PowermaxDiscoveryService} is responsible for discovering
42 * all enrolled zones and X10 devices
44 * @author Laurent Garnier - Initial contribution
45 * @author Laurent Garnier - Use ThingHandlerService
48 public class PowermaxDiscoveryService extends AbstractDiscoveryService
49 implements PowermaxPanelSettingsListener, ThingHandlerService {
51 private static final int SEARCH_TIME = 5;
53 private final Logger logger = LoggerFactory.getLogger(PowermaxDiscoveryService.class);
55 private @Nullable PowermaxBridgeHandler bridgeHandler;
58 * Creates a PowermaxDiscoveryService with background discovery disabled.
60 public PowermaxDiscoveryService() {
61 super(PowermaxBindingConstants.SUPPORTED_THING_TYPES_UIDS, SEARCH_TIME, true);
65 public void setThingHandler(ThingHandler handler) {
66 if (handler instanceof PowermaxBridgeHandler powermaxBridgeHandler) {
67 bridgeHandler = powermaxBridgeHandler;
72 public @Nullable ThingHandler getThingHandler() {
77 * Activates the Discovery Service.
80 public void activate() {
82 PowermaxBridgeHandler handler = bridgeHandler;
83 if (handler != null) {
84 handler.registerPanelSettingsListener(this);
89 * Deactivates the Discovery Service.
92 public void deactivate() {
93 PowermaxBridgeHandler handler = bridgeHandler;
94 if (handler != null) {
95 handler.unregisterPanelSettingsListener(this);
101 protected void startScan() {
102 logger.debug("Updating discovered things (new scan)");
103 PowermaxBridgeHandler handler = bridgeHandler;
104 if (handler != null) {
105 updateFromSettings(handler.getPanelSettings());
110 public void onPanelSettingsUpdated(@Nullable PowermaxPanelSettings settings) {
111 logger.debug("Updating discovered things (global settings updated)");
112 updateFromSettings(settings);
116 public void onZoneSettingsUpdated(int zoneNumber, @Nullable PowermaxPanelSettings settings) {
117 logger.debug("Updating discovered things (zone {} updated)", zoneNumber);
118 PowermaxZoneSettings zoneSettings = (settings == null) ? null : settings.getZoneSettings(zoneNumber);
119 updateFromZoneSettings(zoneNumber, zoneSettings);
122 private void updateFromSettings(@Nullable PowermaxPanelSettings settings) {
123 PowermaxBridgeHandler handler = bridgeHandler;
124 if (handler != null && settings != null) {
125 long beforeUpdate = new Date().getTime();
127 for (int i = 1; i <= settings.getNbZones(); i++) {
128 PowermaxZoneSettings zoneSettings = settings.getZoneSettings(i);
129 updateFromZoneSettings(i, zoneSettings);
132 for (int i = 1; i < settings.getNbPGMX10Devices(); i++) {
133 PowermaxX10Settings deviceSettings = settings.getX10Settings(i);
134 updateFromDeviceSettings(i, deviceSettings);
137 // Remove not updated discovered things
138 removeOlderResults(beforeUpdate, handler.getThing().getUID());
142 private void updateFromZoneSettings(int zoneNumber, @Nullable PowermaxZoneSettings zoneSettings) {
143 PowermaxBridgeHandler handler = bridgeHandler;
144 if (handler != null && zoneSettings != null) {
145 // Prevent for adding already known zone
146 for (Thing thing : handler.getThing().getThings()) {
147 ThingHandler thingHandler = thing.getHandler();
148 if (thing.getThingTypeUID().equals(PowermaxBindingConstants.THING_TYPE_ZONE)
149 && thingHandler instanceof PowermaxThingHandler powermaxThingHandler) {
150 PowermaxZoneConfiguration config = powermaxThingHandler.getZoneConfiguration();
151 if (config.zoneNumber == zoneNumber) {
157 ThingUID bridgeUID = handler.getThing().getUID();
158 ThingUID thingUID = new ThingUID(PowermaxBindingConstants.THING_TYPE_ZONE, bridgeUID,
159 String.valueOf(zoneNumber));
160 String sensorType = zoneSettings.getSensorType();
161 if ("unknown".equalsIgnoreCase(sensorType)) {
162 sensorType = "Sensor";
164 String name = zoneSettings.getName();
165 if ("unknown".equalsIgnoreCase(name)) {
166 name = "Alarm Zone " + zoneNumber;
168 name = sensorType + " " + name;
169 logger.debug("Adding new Powermax alarm zone {} ({}) to inbox", thingUID, name);
170 Map<String, Object> properties = new HashMap<>(1);
171 properties.put(PowermaxZoneConfiguration.ZONE_NUMBER, zoneNumber);
172 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withProperties(properties)
173 .withBridge(bridgeUID).withLabel(name).build();
174 thingDiscovered(discoveryResult);
178 private void updateFromDeviceSettings(int deviceNumber, @Nullable PowermaxX10Settings deviceSettings) {
179 PowermaxBridgeHandler handler = bridgeHandler;
180 if (handler != null && deviceSettings != null && deviceSettings.isEnabled()) {
181 // Prevent for adding already known X10 device
182 for (Thing thing : handler.getThing().getThings()) {
183 ThingHandler thingHandler = thing.getHandler();
184 if (thing.getThingTypeUID().equals(PowermaxBindingConstants.THING_TYPE_X10)
185 && thingHandler instanceof PowermaxThingHandler powermaxThingHandler) {
186 PowermaxX10Configuration config = powermaxThingHandler.getX10Configuration();
187 if (config.deviceNumber == deviceNumber) {
193 ThingUID bridgeUID = handler.getThing().getUID();
194 ThingUID thingUID = new ThingUID(PowermaxBindingConstants.THING_TYPE_X10, bridgeUID,
195 String.valueOf(deviceNumber));
196 String name = (deviceSettings.getName() != null) ? deviceSettings.getName()
197 : ("X10 device " + deviceNumber);
198 logger.debug("Adding new Powermax X10 device {} ({}) to inbox", thingUID, name);
199 Map<String, Object> properties = new HashMap<>(1);
200 properties.put(PowermaxX10Configuration.DEVICE_NUMBER, deviceNumber);
201 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withProperties(properties)
202 .withBridge(bridgeUID).withLabel(name).build();
203 thingDiscovered(discoveryResult);