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.warmup.internal.handler;
15 import static org.openhab.binding.warmup.internal.WarmupBindingConstants.*;
17 import java.math.BigDecimal;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.warmup.internal.api.MyWarmupApiException;
22 import org.openhab.binding.warmup.internal.model.query.LocationDTO;
23 import org.openhab.binding.warmup.internal.model.query.QueryResponseDTO;
24 import org.openhab.binding.warmup.internal.model.query.RoomDTO;
25 import org.openhab.core.library.types.OnOffType;
26 import org.openhab.core.library.types.QuantityType;
27 import org.openhab.core.library.unit.SIUnits;
28 import org.openhab.core.thing.ChannelUID;
29 import org.openhab.core.thing.Thing;
30 import org.openhab.core.thing.ThingStatus;
31 import org.openhab.core.thing.ThingStatusDetail;
32 import org.openhab.core.types.Command;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
37 * @author James Melville - Initial contribution
40 public class RoomHandler extends WarmupThingHandler implements WarmupRefreshListener {
42 private final Logger logger = LoggerFactory.getLogger(RoomHandler.class);
43 private @Nullable RoomConfigurationDTO config;
45 public RoomHandler(Thing thing) {
50 public void initialize() {
52 config = getConfigAs(RoomConfigurationDTO.class);
53 if (config.getSerialNumber().length() == 0) {
54 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Serial Number not configured");
56 super.refreshFromServer();
61 public void handleCommand(ChannelUID channelUID, Command command) {
62 super.handleCommand(channelUID, command);
63 if (CHANNEL_TARGET_TEMPERATURE.equals(channelUID.getId()) && command instanceof QuantityType<?>) {
64 setOverride((QuantityType<?>) command);
66 if (CHANNEL_FROST_PROTECTION_MODE.equals(channelUID.getId()) && command instanceof OnOffType) {
67 toggleFrostProtectionMode((OnOffType) command);
72 * Process device list and populate room properties, status and state
74 * @param domain Data model representing all devices
77 public void refresh(@Nullable QueryResponseDTO domain) {
79 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "No data from bridge");
80 } else if (config != null) {
81 final String serialNumber = config.getSerialNumber();
82 for (LocationDTO location : domain.getData().getUser().getLocations()) {
83 for (RoomDTO room : location.getRooms()) {
84 if (room.getThermostat4ies() != null && !room.getThermostat4ies().isEmpty()
85 && room.getThermostat4ies().get(0).getDeviceSN().equals(serialNumber)) {
86 if (room.getThermostat4ies().get(0).getLastPoll() > 10) {
87 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
88 "Thermostat has not polled for 10 minutes");
90 updateStatus(ThingStatus.ONLINE);
92 updateProperty(PROPERTY_ROOM_ID, room.getId());
93 updateProperty(PROPERTY_ROOM_NAME, room.getName());
94 updateProperty(PROPERTY_LOCATION_ID, location.getId());
95 updateProperty(PROPERTY_LOCATION_NAME, location.getName());
97 updateState(CHANNEL_CURRENT_TEMPERATURE, parseTemperature(room.getCurrentTemperature()));
98 updateState(CHANNEL_TARGET_TEMPERATURE, parseTemperature(room.getTargetTemperature()));
99 updateState(CHANNEL_OVERRIDE_DURATION, parseDuration(room.getOverrideDuration()));
100 updateState(CHANNEL_RUN_MODE, parseString(room.getRunMode()));
101 updateState(CHANNEL_FROST_PROTECTION_MODE,
102 OnOffType.from(room.getRunMode().equals(FROST_PROTECTION_MODE)));
108 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Room not found");
110 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Room not configured");
114 private void setOverride(final QuantityType<?> command) {
115 String roomId = getThing().getProperties().get(PROPERTY_ROOM_ID);
116 String locationId = getThing().getProperties().get(PROPERTY_LOCATION_ID);
118 QuantityType<?> temp = command.toUnit(SIUnits.CELSIUS);
121 final int value = temp.multiply(BigDecimal.TEN).intValue();
124 final MyWarmupAccountHandler bridgeHandler = getBridgeHandler();
125 if (bridgeHandler != null && config != null) {
126 final int overrideDuration = config.getOverrideDuration();
127 if (overrideDuration > 0 && locationId != null && roomId != null) {
128 bridgeHandler.getApi().setOverride(locationId, roomId, value, overrideDuration);
132 } catch (MyWarmupApiException e) {
133 logger.debug("Set Override failed: {}", e.getMessage());
138 private void toggleFrostProtectionMode(OnOffType command) {
139 String roomId = getThing().getProperties().get(PROPERTY_ROOM_ID);
140 String locationId = getThing().getProperties().get(PROPERTY_LOCATION_ID);
142 final MyWarmupAccountHandler bridgeHandler = getBridgeHandler();
143 if (bridgeHandler != null && locationId != null && roomId != null) {
144 bridgeHandler.getApi().toggleFrostProtectionMode(locationId, roomId, command);
147 } catch (MyWarmupApiException e) {
148 logger.debug("Toggle Frost Protection failed: {}", e.getMessage());