/**
* Copyright (c) 2010-2016 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.satel.config;
import java.util.Calendar;
import java.util.Map;
import org.openhab.binding.satel.SatelBindingConfig;
import org.openhab.binding.satel.command.SatelCommand;
import org.openhab.binding.satel.internal.event.ConnectionStatusEvent;
import org.openhab.binding.satel.internal.event.NewStatesEvent;
import org.openhab.binding.satel.internal.event.SatelEvent;
import org.openhab.binding.satel.internal.types.IntegraType;
import org.openhab.core.items.Item;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
import org.openhab.model.item.binding.BindingConfigParseException;
/**
* This class implements binding configuration for various connection status
* values.
*
* Supported options:
* <ul>
* <li>invert_state - for "connected" status, active state is <code>false</code>
* </li>
* </ul>
*
* @author Krzysztof Goworek
* @since 1.8.0
*/
public class ConnectionStatusBindingConfig extends SatelBindingConfig {
enum StatusType {
CONNECTED,
CONNECTED_SINCE,
CONNECTION_ERRORS
}
private StatusType statusType;
private Calendar connectedSince;
private int connectionFailures;
private ConnectionStatusBindingConfig(StatusType statusType, Map<String, String> options) {
super(options);
this.statusType = statusType;
this.connectedSince = null;
this.connectionFailures = 0;
}
/**
* Parses given binding configuration and creates configuration object.
*
* @param bindingConfig
* config to parse
* @return parsed config object or <code>null</code> if config does not
* match
* @throws BindingConfigParseException
* in case of parse errors
*/
public static ConnectionStatusBindingConfig parseConfig(String bindingConfig) throws BindingConfigParseException {
ConfigIterator iterator = new ConfigIterator(bindingConfig);
// check if a status item
if (!"module".equalsIgnoreCase(iterator.next())) {
return null;
}
return new ConnectionStatusBindingConfig(iterator.nextOfType(StatusType.class, "status type"),
iterator.parseOptions());
}
/**
* {@inheritDoc}
*/
@Override
public State convertEventToState(Item item, SatelEvent event) {
if (!(event instanceof ConnectionStatusEvent)) {
// since we get event about changes, we assume connection has been established.
// if current items state is uninitialized, "generate" fake event to update its state
if (event instanceof NewStatesEvent && this.connectedSince == null) {
event = new ConnectionStatusEvent(true);
} else {
return null;
}
}
ConnectionStatusEvent statusEvent = (ConnectionStatusEvent) event;
boolean invertState = hasOptionEnabled(Options.INVERT_STATE);
// update internal values
if (statusEvent.isConnected()) {
this.connectionFailures = 0;
if (this.connectedSince == null) {
this.connectedSince = Calendar.getInstance();
}
} else {
this.connectionFailures += 1;
this.connectedSince = null;
}
switch (this.statusType) {
case CONNECTED:
return booleanToState(item, statusEvent.isConnected() ^ invertState);
case CONNECTED_SINCE:
if (this.connectedSince == null) {
return UnDefType.NULL;
} else if (item.getAcceptedDataTypes().contains(DateTimeType.class)) {
return new DateTimeType(this.connectedSince);
}
break;
case CONNECTION_ERRORS:
if (item.getAcceptedDataTypes().contains(DecimalType.class)) {
return new DecimalType(this.connectionFailures);
}
break;
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
public SatelCommand convertCommand(Command command, IntegraType integraType, String userCode) {
// this configuration does not accept commands
return null;
}
/**
* {@inheritDoc}
*/
@Override
public SatelCommand buildRefreshCommand(IntegraType integraType) {
// this is configuration for internal state - does not need refresh
// command
return null;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return String.format("%s: status = %s, options = %s", this.getClass().getName(), this.statusType,
this.optionsAsString());
}
}