]> git.basschouten.com Git - openhab-addons.git/blob
c5a73297dd447e589250fde315fb522b73bd7966
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.enphase.internal.handler;
14
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.eclipse.jetty.client.HttpClient;
18 import org.openhab.binding.enphase.internal.EnvoyConfiguration;
19 import org.openhab.binding.enphase.internal.exception.EnphaseException;
20 import org.openhab.binding.enphase.internal.exception.EnvoyConnectionException;
21 import org.openhab.binding.enphase.internal.exception.EnvoyNoHostnameException;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 /**
26  * Wraps around the specific Envoy connector and provides methods to determine which connector to use.
27  *
28  * @author Hilbrand Bouwkamp - Initial contribution
29  */
30 @NonNullByDefault
31 public class EnvoyConnectorWrapper {
32
33     private final Logger logger = LoggerFactory.getLogger(EnvoyConnectorWrapper.class);
34     private final HttpClient httpClient;
35     private @Nullable EnvoyConnector connector;
36     private @Nullable String version;
37
38     public EnvoyConnectorWrapper(final HttpClient httpClient) {
39         this.httpClient = httpClient;
40     }
41
42     public @Nullable String getVersion() {
43         return version;
44     }
45
46     /**
47      * Sets the Envoy software version as retreived from the Envoy data.
48      *
49      * @param version Envoy software version.
50      */
51     public void setVersion(final @Nullable String version) {
52         if (version == null) {
53             return;
54         }
55         logger.debug("Set Envoy version found in the Envoy data: {}", version);
56         this.version = version;
57     }
58
59     /**
60      * Set the connector given the configuration.
61      *
62      * @param configuration configuration to use to set the connector.
63      * @return Returns configuration error message or empty string if no configuration errors present
64      * @throws EnphaseException
65      */
66     public synchronized String setConnector(final EnvoyConfiguration configuration) throws EnphaseException {
67         final EnvoyConnector connector = determineConnector(configuration.hostname);
68         final String message = connector.setConfiguration(configuration);
69
70         // Only set connector if no error messages.
71         if (message.isEmpty()) {
72             this.connector = connector;
73         }
74         return message;
75     }
76
77     /**
78      * @return Returns true if a connection with the Envoy has been established.
79      */
80     public boolean hasConnection() {
81         return connector != null;
82     }
83
84     /**
85      * @return Returns the connector when present. This method should only be called when a connector is present as
86      *         returned by the {@link #hasConnection()} method.
87      */
88     public EnvoyConnector getConnector() throws EnvoyConnectionException {
89         final EnvoyConnector connector = this.connector;
90
91         if (connector == null) {
92             throw new EnvoyConnectionException("No connection to the Envoy. Check your configuration.");
93         }
94         return connector;
95     }
96
97     private EnvoyConnector determineConnector(final String hostname) throws EnphaseException {
98         final EnvoyConnector connectorByVersion = determineConnectorOnVersion();
99
100         if (connectorByVersion != null) {
101             return connectorByVersion;
102         }
103
104         if (hostname.isBlank()) {
105             throw new EnvoyNoHostnameException("No hostname available.");
106         }
107         final EnvoyConnector envoyConnector = new EnvoyConnector(httpClient);
108         final String version = envoyConnector.checkConnection(hostname);
109
110         if (version != null) {
111             this.version = version;
112             final int majorVersionNumber = determineMajorVersionNumber();
113
114             if (majorVersionNumber > 0 && majorVersionNumber < 7) {
115                 logger.debug(
116                         "Connection to Envoy determined by getting a reply from the Envoy using the prior to version 7 method.");
117                 return envoyConnector;
118             }
119             if (majorVersionNumber >= 7) {
120                 logger.debug(
121                         "Connection to Envoy determined by getting a reply from the Envoy using version 7 connection method.");
122                 return new EnvoyEntrezConnector(httpClient);
123             }
124         }
125         final EnvoyEntrezConnector envoyEntrezConnector = new EnvoyEntrezConnector(httpClient);
126         final String entrezVersion = envoyEntrezConnector.checkConnection(hostname);
127
128         if (entrezVersion != null) {
129             this.version = entrezVersion;
130             final int majorVersionNumber = determineMajorVersionNumber();
131
132             if (majorVersionNumber >= 7) {
133                 logger.info(
134                         "Connection to Envoy determined by getting a reply from the Envoy using version 7 connection method.");
135                 return envoyEntrezConnector;
136             }
137         }
138         throw new EnphaseException("No connection could be made with the Envoy. Check your connection/hostname.");
139     }
140
141     private @Nullable EnvoyConnector determineConnectorOnVersion() {
142         final int majorVersionNumber = determineMajorVersionNumber();
143
144         if (majorVersionNumber < 0) {
145             return null;
146         } else if (majorVersionNumber < 7) {
147             logger.debug("Connect to Envoy based on version number {} using standard connector", version);
148             return new EnvoyConnector(httpClient);
149         } else {
150             logger.debug("Connect to Envoy based on version number {} using entrez connector", version);
151             return new EnvoyEntrezConnector(httpClient);
152         }
153     }
154
155     private int determineMajorVersionNumber() {
156         final String version = this.version;
157
158         if (version == null) {
159             return -1;
160         }
161         logger.debug("Envoy version information used to determine actual version: {}", version);
162         final int marjorVersionIndex = version.indexOf('.');
163
164         if (marjorVersionIndex < 0) {
165             return -1;
166         }
167         try {
168             return Integer.parseInt(version.substring(0, marjorVersionIndex));
169         } catch (final NumberFormatException e) {
170             logger.trace("Could not parse major version number in {}, error message: {}", version, e.getMessage());
171             return -1;
172         }
173     }
174 }