org.openhab.binding.nest.handler.NestBaseHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.openhab.binding.nest.handler.NestBaseHandler.java

Source

/**
 * Copyright (c) 2010-2018 by the respective copyright holders.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.openhab.binding.nest.handler;

import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.Date;
import java.util.TimeZone;

import javax.measure.Quantity;
import javax.measure.Unit;

import org.apache.commons.lang.StringUtils;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.library.types.DateTimeType;
import org.eclipse.smarthome.core.library.types.DecimalType;
import org.eclipse.smarthome.core.library.types.OnOffType;
import org.eclipse.smarthome.core.library.types.QuantityType;
import org.eclipse.smarthome.core.library.types.StringType;
import org.eclipse.smarthome.core.thing.Bridge;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.ThingStatus;
import org.eclipse.smarthome.core.thing.ThingStatusDetail;
import org.eclipse.smarthome.core.thing.binding.BaseThingHandler;
import org.eclipse.smarthome.core.types.State;
import org.eclipse.smarthome.core.types.UnDefType;
import org.openhab.binding.nest.internal.config.NestDeviceConfiguration;
import org.openhab.binding.nest.internal.data.Camera;
import org.openhab.binding.nest.internal.data.NestIdentifiable;
import org.openhab.binding.nest.internal.data.SmokeDetector;
import org.openhab.binding.nest.internal.data.Structure;
import org.openhab.binding.nest.internal.data.Thermostat;
import org.openhab.binding.nest.internal.listener.NestDeviceDataListener;
import org.openhab.binding.nest.internal.rest.NestUpdateRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Deals with the structures on the Nest API, turning them into a thing in openHAB.
 *
 * @author David Bennett - initial contribution
 * @author Martin van Wingerden - Splitted of NestBaseHandler
 * @author Wouter Born - Add generic update data type
 *
 * @param <T> the type of update data
 */
@NonNullByDefault
abstract class NestBaseHandler<T> extends BaseThingHandler implements NestDeviceDataListener, NestIdentifiable {
    private final Logger logger = LoggerFactory.getLogger(NestBaseHandler.class);

    private @Nullable T lastUpdate;

    NestBaseHandler(Thing thing) {
        super(thing);
    }

    protected @Nullable T getLastUpdate() {
        return lastUpdate;
    }

    protected void setLastUpdate(T lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

    @Override
    public void initialize() {
        logger.debug("Initializing handler for {}", getClass().getName());
        if (getNestBridgeHandler() != null) {
            boolean success = getNestBridgeHandler().addDeviceDataListener(this);
            logger.debug("Adding {} with ID '{}' as device data listener, result: {}", getClass().getSimpleName(),
                    getId(), success);
        } else {
            logger.debug("Unable to add {} with ID '{}' as device data listener because bridge is null");
        }

        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, "Waiting for refresh");
    }

    @Override
    public void dispose() {
        NestBridgeHandler handler = getNestBridgeHandler();
        if (handler != null) {
            handler.removeDeviceDataListener(this);
        }
    }

    protected void addUpdateRequest(String updatePath, String field, Object value) {
        NestBridgeHandler handler = getNestBridgeHandler();
        if (handler != null) {
            // @formatter:off
            handler.addUpdateRequest(new NestUpdateRequest.Builder().withBasePath(updatePath)
                    .withIdentifier(getId()).withAdditionalValue(field, value).build());
            // @formatter:on
        }
    }

    @Override
    public String getId() {
        return getDeviceId();
    }

    protected String getDeviceId() {
        return getConfigAs(NestDeviceConfiguration.class).deviceId;
    }

    protected @Nullable NestBridgeHandler getNestBridgeHandler() {
        Bridge bridge = getBridge();
        return bridge != null ? (NestBridgeHandler) bridge.getHandler() : null;
    }

    protected abstract State getChannelState(ChannelUID channelUID, T data);

    protected State getAsDateTimeTypeOrNull(@Nullable Date date) {
        if (date == null) {
            return UnDefType.NULL;
        }

        long offsetMillis = TimeZone.getDefault().getOffset(date.getTime());
        Instant instant = date.toInstant().plusMillis(offsetMillis);
        return new DateTimeType(ZonedDateTime.ofInstant(instant, TimeZone.getDefault().toZoneId()));
    }

    protected State getAsDecimalTypeOrNull(@Nullable Integer value) {
        return value == null ? UnDefType.NULL : new DecimalType(value);
    }

    protected State getAsOnOffTypeOrNull(@Nullable Boolean value) {
        return value == null ? UnDefType.NULL : value ? OnOffType.ON : OnOffType.OFF;
    }

    protected <U extends Quantity<U>> State getAsQuantityTypeOrNull(@Nullable Number value, Unit<U> unit) {
        return value == null ? UnDefType.NULL : new QuantityType<U>(value, unit);
    }

    protected State getAsStringTypeOrNull(@Nullable Object value) {
        return value == null ? UnDefType.NULL : new StringType(value.toString());
    }

    protected State getAsStringTypeListOrNull(@Nullable Collection<? extends Object> values) {
        return values == null || values.isEmpty() ? UnDefType.NULL : new StringType(StringUtils.join(values, ","));
    }

    protected boolean isNotHandling(NestIdentifiable nestIdentifiable) {
        return !(getId().equals(nestIdentifiable.getId()));
    }

    protected void updateChannels(T data) {
        getThing().getChannels().forEach(c -> updateState(c.getUID(), getChannelState(c.getUID(), data)));
    }

    @Override
    public void onNewNestCameraData(Camera camera) {
        // can be overridden by subclasses for handling new camera data
    }

    @Override
    public void onNewNestSmokeDetectorData(SmokeDetector smokeDetector) {
        // can be overridden by subclasses for handling new smoke detector data
    }

    @Override
    public void onNewNestStructureData(Structure structure) {
        // can be overridden by subclasses for handling new structure data
    }

    @Override
    public void onNewNestThermostatData(Thermostat thermostat) {
        // can be overridden by subclasses for handling new thermostat data
    }
}