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.boschshc.internal.devices.userdefinedstate;
15 import static org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants.CHANNEL_USER_DEFINED_STATE;
17 import java.util.List;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.TimeoutException;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.boschshc.internal.devices.BoschSHCConfiguration;
24 import org.openhab.binding.boschshc.internal.devices.BoschSHCHandler;
25 import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
26 import org.openhab.binding.boschshc.internal.services.userstate.UserStateService;
27 import org.openhab.binding.boschshc.internal.services.userstate.dto.UserStateServiceState;
28 import org.openhab.core.library.types.OnOffType;
29 import org.openhab.core.thing.ChannelUID;
30 import org.openhab.core.thing.Thing;
31 import org.openhab.core.thing.ThingStatus;
32 import org.openhab.core.thing.ThingStatusDetail;
33 import org.openhab.core.types.Command;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 import com.google.gson.JsonElement;
40 * Handler for user defined states
42 * @author Patrick Gell - Initial contribution
46 public class UserStateHandler extends BoschSHCHandler {
48 private final Logger logger = LoggerFactory.getLogger(getClass());
50 private final UserStateService userStateService;
52 * Bosch SHC configuration loaded from openHAB configuration.
54 private @Nullable BoschSHCConfiguration config;
56 public UserStateHandler(Thing thing) {
59 userStateService = new UserStateService();
63 public void initialize() {
64 var localConfig = this.config = getConfigAs(BoschSHCConfiguration.class);
65 String stateId = localConfig.id;
66 if (stateId == null || stateId.isBlank()) {
67 this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
68 "@text/offline.conf-error.empty-state-id");
72 // Try to get state info to make sure the state exists
74 var bridgeHandler = this.getBridgeHandler();
75 var info = bridgeHandler.getUserStateInfo(stateId);
76 logger.trace("User-defined state initialized:\n{}", info);
77 } catch (TimeoutException | ExecutionException | BoschSHCException e) {
78 this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
80 } catch (InterruptedException e) {
81 Thread.currentThread().interrupt();
82 this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
89 public @Nullable String getBoschID() {
98 protected void initializeServices() throws BoschSHCException {
99 super.initializeServices();
101 logger.debug("Initializing service for UserStateHandler");
102 this.registerService(userStateService, this::updateChannels, List.of(CHANNEL_USER_DEFINED_STATE), true);
106 public void handleCommand(ChannelUID channelUID, Command command) {
107 super.handleCommand(channelUID, command);
109 if (channelUID.getId().equals(CHANNEL_USER_DEFINED_STATE) && (command instanceof OnOffType onOffCommand)) {
110 updateUserState(channelUID.getThingUID().getId(), onOffCommand);
114 private void updateUserState(String stateId, OnOffType userState) {
115 UserStateServiceState serviceState = new UserStateServiceState();
116 serviceState.setState(userState == OnOffType.ON);
118 getBridgeHandler().putState(stateId, "", serviceState);
119 } catch (BoschSHCException | ExecutionException | TimeoutException e) {
120 this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
121 String.format("Error while putting user-defined state for %s", stateId));
122 } catch (InterruptedException e) {
123 Thread.currentThread().interrupt();
124 this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
125 String.format("Error while putting user-defined state for %s", stateId));
129 private void updateChannels(UserStateServiceState userState) {
130 super.updateState(CHANNEL_USER_DEFINED_STATE, userState.toOnOffType());
134 public void processUpdate(String serviceName, @Nullable JsonElement stateData) {
135 super.processUpdate("UserDefinedState", stateData);