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.mybmw.internal.handler;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.List;
18 import java.util.Optional;
19 import java.util.concurrent.ScheduledFuture;
20 import java.util.concurrent.TimeUnit;
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.binding.mybmw.internal.MyBMWConfiguration;
25 import org.openhab.binding.mybmw.internal.discovery.VehicleDiscovery;
26 import org.openhab.binding.mybmw.internal.dto.network.NetworkError;
27 import org.openhab.binding.mybmw.internal.dto.vehicle.Vehicle;
28 import org.openhab.binding.mybmw.internal.utils.BimmerConstants;
29 import org.openhab.binding.mybmw.internal.utils.Constants;
30 import org.openhab.binding.mybmw.internal.utils.Converter;
31 import org.openhab.core.io.net.http.HttpClientFactory;
32 import org.openhab.core.thing.Bridge;
33 import org.openhab.core.thing.ChannelUID;
34 import org.openhab.core.thing.ThingStatus;
35 import org.openhab.core.thing.ThingStatusDetail;
36 import org.openhab.core.thing.binding.BaseBridgeHandler;
37 import org.openhab.core.thing.binding.ThingHandlerService;
38 import org.openhab.core.types.Command;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
43 * The {@link MyBMWBridgeHandler} is responsible for handling commands, which are
44 * sent to one of the channels.
46 * @author Bernd Weymann - Initial contribution
49 public class MyBMWBridgeHandler extends BaseBridgeHandler implements StringResponseCallback {
50 private final Logger logger = LoggerFactory.getLogger(MyBMWBridgeHandler.class);
51 private HttpClientFactory httpClientFactory;
52 private Optional<VehicleDiscovery> discoveryService = Optional.empty();
53 private Optional<MyBMWProxy> proxy = Optional.empty();
54 private Optional<ScheduledFuture<?>> initializerJob = Optional.empty();
55 private Optional<String> troubleshootFingerprint = Optional.empty();
56 private String localeLanguage;
58 public MyBMWBridgeHandler(Bridge bridge, HttpClientFactory hcf, String language) {
60 httpClientFactory = hcf;
61 localeLanguage = language;
65 public void handleCommand(ChannelUID channelUID, Command command) {
66 // no commands available
70 public void initialize() {
71 troubleshootFingerprint = Optional.empty();
72 updateStatus(ThingStatus.UNKNOWN);
73 MyBMWConfiguration config = getConfigAs(MyBMWConfiguration.class);
74 if (config.language.equals(Constants.LANGUAGE_AUTODETECT)) {
75 config.language = localeLanguage;
77 if (!checkConfiguration(config)) {
78 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
80 proxy = Optional.of(new MyBMWProxy(httpClientFactory, config));
81 initializerJob = Optional.of(scheduler.schedule(this::requestVehicles, 2, TimeUnit.SECONDS));
85 public static boolean checkConfiguration(MyBMWConfiguration config) {
86 if (Constants.EMPTY.equals(config.userName) || Constants.EMPTY.equals(config.password)) {
89 return BimmerConstants.EADRAX_SERVER_MAP.containsKey(config.region);
94 public void dispose() {
95 initializerJob.ifPresent(job -> job.cancel(true));
98 public void requestVehicles() {
99 proxy.ifPresent(prox -> prox.requestVehicles(this));
102 private void logFingerPrint() {
103 logger.debug("###### Discovery Fingerprint Data - BEGIN ######");
104 logger.debug("{}", troubleshootFingerprint.get());
105 logger.debug("###### Discovery Fingerprint Data - END ######");
109 * Response for vehicle request
112 public synchronized void onResponse(@Nullable String response) {
113 if (response != null) {
114 updateStatus(ThingStatus.ONLINE);
115 List<Vehicle> vehicleList = Converter.getVehicleList(response);
116 discoveryService.get().onResponse(vehicleList);
117 troubleshootFingerprint = Optional.of(Converter.anonymousFingerprint(response));
123 public void onError(NetworkError error) {
124 troubleshootFingerprint = Optional.of(error.toJson());
126 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error.reason);
130 public Collection<Class<? extends ThingHandlerService>> getServices() {
131 return Collections.singleton(VehicleDiscovery.class);
134 public Optional<MyBMWProxy> getProxy() {
138 public void setDiscoveryService(VehicleDiscovery discoveryService) {
139 this.discoveryService = Optional.of(discoveryService);