]> git.basschouten.com Git - openhab-addons.git/blob
431f78b5c847473070a81e37609ce96a9602440c
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.teleinfo.internal;
14
15 import static org.openhab.binding.teleinfo.internal.TeleinfoBindingConstants.*;
16
17 import java.util.HashMap;
18 import java.util.Map;
19 import java.util.Set;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.teleinfo.internal.data.Frame;
23 import org.openhab.binding.teleinfo.internal.handler.TeleinfoAbstractControllerHandler;
24 import org.openhab.binding.teleinfo.internal.handler.TeleinfoControllerHandlerListener;
25 import org.openhab.binding.teleinfo.internal.reader.io.serialport.InvalidFrameException;
26 import org.openhab.binding.teleinfo.internal.reader.io.serialport.Label;
27 import org.openhab.core.config.discovery.AbstractThingHandlerDiscoveryService;
28 import org.openhab.core.config.discovery.DiscoveryResult;
29 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
30 import org.openhab.core.thing.ThingTypeUID;
31 import org.openhab.core.thing.ThingUID;
32 import org.osgi.service.component.annotations.Component;
33 import org.osgi.service.component.annotations.ServiceScope;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 /**
38  * The {@link TeleinfoDiscoveryService} class is the service to discover a skeleton for controller handlers.
39  *
40  * @author Nicolas SIBERIL - Initial contribution
41  */
42 @Component(scope = ServiceScope.PROTOTYPE, service = TeleinfoDiscoveryService.class)
43 @NonNullByDefault
44 public class TeleinfoDiscoveryService extends AbstractThingHandlerDiscoveryService<TeleinfoAbstractControllerHandler>
45         implements TeleinfoControllerHandlerListener {
46
47     private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_HC_CBEMM_ELECTRICITY_METER_TYPE_UID,
48             THING_BASE_CBEMM_ELECTRICITY_METER_TYPE_UID, THING_TEMPO_CBEMM_ELECTRICITY_METER_TYPE_UID,
49             THING_EJP_CBEMM_ELECTRICITY_METER_TYPE_UID, THING_HC_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID,
50             THING_BASE_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID, THING_TEMPO_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID,
51             THING_EJP_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID, THING_HC_CBETM_ELECTRICITY_METER_TYPE_UID,
52             THING_BASE_CBETM_ELECTRICITY_METER_TYPE_UID, THING_TEMPO_CBETM_ELECTRICITY_METER_TYPE_UID,
53             THING_EJP_CBETM_ELECTRICITY_METER_TYPE_UID, THING_LSMT_PROD_ELECTRICITY_METER_TYPE_UID,
54             THING_LSMT_ELECTRICITY_METER_TYPE_UID, THING_LSMM_PROD_ELECTRICITY_METER_TYPE_UID,
55             THING_LSMM_ELECTRICITY_METER_TYPE_UID);
56
57     private static final int SCAN_DURATION_IN_S = 60;
58
59     private final Logger logger = LoggerFactory.getLogger(TeleinfoDiscoveryService.class);
60
61     public TeleinfoDiscoveryService() {
62         super(TeleinfoAbstractControllerHandler.class, SCAN_DURATION_IN_S);
63     }
64
65     public TeleinfoDiscoveryService(TeleinfoAbstractControllerHandler controllerHandler) {
66         this();
67         setThingHandler(controllerHandler);
68     }
69
70     @Override
71     public Set<ThingTypeUID> getSupportedThingTypes() {
72         return SUPPORTED_THING_TYPES;
73     }
74
75     @Override
76     protected void startScan() {
77         logger.debug("Teleinfo discovery: Start {}", thingHandler.getThing().getUID());
78
79         // Start the search for new devices
80         thingHandler.addListener(this);
81     }
82
83     @Override
84     public synchronized void abortScan() {
85         logger.debug("Teleinfo discovery: Abort {}", thingHandler.getThing().getUID());
86         thingHandler.removeListener(this);
87         super.abortScan();
88     }
89
90     @Override
91     protected synchronized void stopScan() {
92         logger.debug("Teleinfo discovery: Stop {}", thingHandler.getThing().getUID());
93         thingHandler.removeListener(this);
94         super.stopScan();
95     }
96
97     @Override
98     public void onFrameReceived(Frame frame) {
99         detectNewElectricityMeterFromReceivedFrame(frame);
100     }
101
102     private void detectNewElectricityMeterFromReceivedFrame(final Frame frameSample) {
103         logger.debug("New eletricity meter detection from frame {}", frameSample);
104         if (frameSample.get(Label.ADCO) == null && frameSample.get(Label.ADSC) == null) {
105             throw new IllegalStateException("Missing ADCO or ADSC key");
106         }
107
108         String adco = frameSample.get(Label.ADCO) != null ? frameSample.get(Label.ADCO) : frameSample.get(Label.ADSC);
109         if (adco != null) {
110             ThingUID thingUID = new ThingUID(getThingTypeUID(frameSample), adco,
111                     thingHandler.getThing().getUID().getId());
112
113             final Map<String, Object> properties = getThingProperties(adco);
114             final String representationProperty = THING_ELECTRICITY_METER_PROPERTY_ADCO;
115             DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withProperties(properties)
116                     .withLabel("Teleinfo ADCO/ADSC " + adco).withThingType(getThingTypeUID(frameSample))
117                     .withBridge(thingHandler.getThing().getUID()).withRepresentationProperty(representationProperty)
118                     .build();
119
120             thingDiscovered(discoveryResult);
121         }
122     }
123
124     private ThingTypeUID getThingTypeUID(final Frame teleinfoFrame) {
125         ThingTypeUID thingTypeUID;
126         try {
127             thingTypeUID = teleinfoFrame.getType().getThingTypeUid();
128         } catch (InvalidFrameException e) {
129             throw new IllegalStateException("Frame type can not be evaluated");
130         }
131         if (thingTypeUID != null) {
132             return thingTypeUID;
133         } else {
134             throw new IllegalStateException("Teleinfo frame type not supported: " + teleinfoFrame.getClass());
135         }
136     }
137
138     private Map<String, Object> getThingProperties(String adco) {
139         Map<String, Object> properties = new HashMap<>();
140         properties.put(THING_ELECTRICITY_METER_PROPERTY_ADCO, adco);
141
142         return properties;
143     }
144 }