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.easee.internal.discovery;
15 import static org.openhab.binding.easee.internal.EaseeBindingConstants.*;
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.openhab.binding.easee.internal.EaseeBindingConstants;
20 import org.openhab.binding.easee.internal.Utils;
21 import org.openhab.binding.easee.internal.command.site.GetSite;
22 import org.openhab.binding.easee.internal.connector.CommunicationStatus;
23 import org.openhab.binding.easee.internal.handler.EaseeSiteHandler;
24 import org.openhab.core.config.discovery.AbstractDiscoveryService;
25 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
26 import org.openhab.core.thing.ThingTypeUID;
27 import org.openhab.core.thing.ThingUID;
28 import org.openhab.core.thing.binding.ThingHandler;
29 import org.openhab.core.thing.binding.ThingHandlerService;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
33 import com.google.gson.JsonArray;
34 import com.google.gson.JsonElement;
35 import com.google.gson.JsonObject;
38 * this class will handle discovery of wallboxes and circuits within the site configured.
40 * @author Alexander Friese - initial contribution
44 public class EaseeSiteDiscoveryService extends AbstractDiscoveryService implements ThingHandlerService {
46 private final Logger logger = LoggerFactory.getLogger(EaseeSiteDiscoveryService.class);
47 private @NonNullByDefault({}) EaseeSiteHandler bridgeHandler;
49 public EaseeSiteDiscoveryService() throws IllegalArgumentException {
50 super(EaseeBindingConstants.SUPPORTED_THING_TYPES_UIDS, 300, false);
54 protected void startScan() {
55 bridgeHandler.enqueueCommand(new GetSite(bridgeHandler, this::processSiteDiscoveryResult));
59 public void setThingHandler(ThingHandler handler) {
60 if (handler instanceof EaseeSiteHandler siteHandler) {
61 this.bridgeHandler = siteHandler;
62 this.bridgeHandler.setDiscoveryService(this);
67 public @Nullable ThingHandler getThingHandler() {
71 // method is defined in both implemented interface and inherited class, thus we must define a behaviour here.
73 public void deactivate() {
78 * callback that handles json result data to provide discovery result.
82 private void processSiteDiscoveryResult(CommunicationStatus status, JsonObject site) {
83 logger.debug("processDiscoveryResult {}", site);
85 JsonArray circuits = site.getAsJsonArray(JSON_KEY_CIRCUITS);
86 if (circuits == null) {
87 logger.info("Site discovery failed, no circuits found.");
89 circuits.forEach(this::handleCircuitDiscovery);
94 * handles each circuit discovery result.
98 private void handleCircuitDiscovery(JsonElement json) {
99 logger.debug("handleCircuitDiscovery {}", json);
101 JsonObject circuit = json.getAsJsonObject();
102 final String circuitId = Utils.getAsString(circuit, JSON_KEY_GENERIC_ID);
103 final String circuitName = Utils.getAsString(circuit, JSON_KEY_CIRCUIT_NAME);
105 if (circuitId != null) {
106 final String circuitLabel = circuitName != null ? circuitName : circuitId;
108 // handle contained chargers
109 JsonArray chargers = circuit.getAsJsonArray(JSON_KEY_CHARGERS);
110 if (chargers == null) {
111 logger.info("Site discovery failed, no chargers found.");
113 chargers.forEach(charger -> handleChargerDiscovery(charger, circuitId, circuitLabel));
119 * handles each charger discovery result.
123 private void handleChargerDiscovery(JsonElement json, String circuitId, String circuitLabel) {
124 logger.debug("handleChargerDiscovery {}", json);
126 JsonObject charger = json.getAsJsonObject();
127 String chargerId = Utils.getAsString(charger, JSON_KEY_GENERIC_ID);
128 String backPlateId = Utils.getAsString(charger.getAsJsonObject(JSON_KEY_BACK_PLATE), JSON_KEY_GENERIC_ID);
129 String masterBackPlateId = Utils.getAsString(charger.getAsJsonObject(JSON_KEY_BACK_PLATE),
130 JSON_KEY_MASTER_BACK_PLATE_ID);
131 String chargerName = Utils.getAsString(charger, JSON_KEY_GENERIC_NAME);
133 if (chargerId != null && backPlateId != null && masterBackPlateId != null) {
134 DiscoveryResultBuilder builder;
136 if (backPlateId.equals(masterBackPlateId)) {
137 builder = initDiscoveryResultBuilder(DEVICE_MASTER_CHARGER, chargerId, chargerName)
138 .withProperty(THING_CONFIG_IS_MASTER, GENERIC_YES);
140 builder = initDiscoveryResultBuilder(DEVICE_CHARGER, chargerId, chargerName)
141 .withProperty(THING_CONFIG_IS_MASTER, GENERIC_NO);
143 builder.withProperty(THING_CONFIG_CIRCUIT_ID, circuitId);
144 builder.withProperty(THING_CONFIG_CIRCUIT_NAME, circuitLabel);
145 builder.withProperty(THING_CONFIG_BACK_PLATE_ID, backPlateId);
146 builder.withProperty(THING_CONFIG_MASTER_BACK_PLATE_ID, masterBackPlateId);
147 thingDiscovered(builder.build());
152 * sends discovery notification to the framework.
158 private DiscoveryResultBuilder initDiscoveryResultBuilder(String deviceType, String deviceId,
159 @Nullable String deviceName) {
160 ThingUID bridgeUID = bridgeHandler.getThing().getUID();
161 ThingTypeUID typeUid = new ThingTypeUID(BINDING_ID, deviceType);
163 ThingUID thingUID = new ThingUID(typeUid, bridgeUID, deviceId);
164 String label = deviceName != null ? deviceName : deviceId;
166 return DiscoveryResultBuilder.create(thingUID).withBridge(bridgeUID).withLabel(label)
167 .withProperty(THING_CONFIG_ID, deviceId).withRepresentationProperty(THING_CONFIG_ID);