/** * 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.internal.event; import java.util.BitSet; import java.util.HashMap; import java.util.Map; import org.openhab.binding.satel.internal.types.StateType; /** * Event class describing current state of zones/partitions/outputs/doors/troubles. * * @author Krzysztof Goworek * @since 1.7.0 */ public class IntegraStateEvent implements SatelEvent { private byte command; private BitSet stateBits; private boolean extendedData; private Map<StateType, BitSet> stateBitsMap = new HashMap<>(); /** * Constructs new event instance from given state type and state bits. * * @param command the command byte * @param stateBits state bits as byte array * @param extendedData whether state bits are for extended command */ public IntegraStateEvent(byte command, byte[] stateBits, boolean extendedData) { this.command = command; this.stateBits = BitSet.valueOf(stateBits); this.extendedData = extendedData; } /** * Checks whether data in the event is valid for given type of state. * * @param stateType state type * @return <code>true</code> if this event is valid for given stae */ public boolean hasDataForState(StateType stateType) { return stateType.getRefreshCommand() == this.command; } /** * Returns state bits as {@link BitSet}. * * @param stateType type of state * @return bits for given state * @throws IllegalArgumentException when wrong state type given */ public BitSet getStateBits(StateType stateType) { if (!hasDataForState(stateType)) { throw new IllegalArgumentException("Event does not have data for " + stateType); } int bitsCount = stateType.getBytesCount(extendedData) * 8; // whole payload is a single state if (stateType.getStartByte() == 0 && bitsCount == stateBits.size()) { return stateBits; } BitSet result = stateBitsMap.get(stateType); if (result == null) { int startBit = stateType.getStartByte() * 8; result = stateBits.get(startBit, startBit + bitsCount); stateBitsMap.put(stateType, result); } return result; } /** * Returns <code>true</code> if specified state bit is set for given state. * * @param stateType type of state * @param nbr state bit number * @return <code>true</code> if state bit is set */ public boolean isSet(StateType stateType, int nbr) { return getStateBits(stateType).get(nbr); } /** * Returns number of state bits that are active for given state. * * @param stateType type of state * @return number of active states */ public int statesSet(StateType stateType) { return getStateBits(stateType).cardinality(); } /** * {@inheritDoc} */ @Override public String toString() { return String.format("IntegraStateEvent: command = %02X, extended = %b, active = %s", command, extendedData, stateBits); } }