forked from openhab/openhab-addons
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Initial Russound Implementation (openhab#1225) Signed-off-by: Tim Roberts <troberts@bigfoot.com>
- Loading branch information
Showing
47 changed files
with
7,549 additions
and
0 deletions.
There are no files selected for viewing
135 changes: 135 additions & 0 deletions
135
...ing.atlona/src/main/java/org/openhab/binding/atlona/internal/StatefulHandlerCallback.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/** | ||
* Copyright (c) 2014-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.atlona.internal; | ||
|
||
import java.util.Map; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
import java.util.concurrent.locks.Lock; | ||
import java.util.concurrent.locks.ReentrantLock; | ||
|
||
import org.apache.commons.lang.StringUtils; | ||
import org.eclipse.smarthome.core.thing.ThingStatus; | ||
import org.eclipse.smarthome.core.thing.ThingStatusDetail; | ||
import org.eclipse.smarthome.core.types.State; | ||
|
||
/** | ||
* Defines an implementation of {@link AtlonaHandlerCallback} that will remember the last state | ||
* for an channelId and suppress the callback if the state hasn't changed | ||
* | ||
* @author Tim Roberts | ||
* | ||
*/ | ||
public class StatefulHandlerCallback implements AtlonaHandlerCallback { | ||
|
||
/** The wrapped callback */ | ||
private final AtlonaHandlerCallback _wrappedCallback; | ||
|
||
/** The state by channel id */ | ||
private final Map<String, State> _state = new ConcurrentHashMap<String, State>(); | ||
|
||
private final Lock _statusLock = new ReentrantLock(); | ||
private ThingStatus _lastThingStatus = null; | ||
private ThingStatusDetail _lastThingStatusDetail = null; | ||
|
||
/** | ||
* Create the callback from the other {@link AtlonaHandlerCallback} | ||
* | ||
* @param wrappedCallback a non-null {@link AtlonaHandlerCallback} | ||
* @throws NullPointerException if wrappedCallback is null | ||
*/ | ||
public StatefulHandlerCallback(AtlonaHandlerCallback wrappedCallback) { | ||
if (wrappedCallback == null) { | ||
throw new NullPointerException("wrappedCallback cannot be null"); | ||
} | ||
|
||
_wrappedCallback = wrappedCallback; | ||
} | ||
|
||
/** | ||
* Overrides the status changed to simply call the {@link #_wrappedCallback} | ||
* | ||
* @param status the new status | ||
* @param detail the new detail | ||
* @param msg the new message | ||
*/ | ||
@Override | ||
public void statusChanged(ThingStatus status, ThingStatusDetail detail, String msg) { | ||
_statusLock.lock(); | ||
try { | ||
// Simply return we match the last status change (prevents loops if changing to the same status) | ||
if (status == _lastThingStatus && detail == _lastThingStatusDetail) { | ||
return; | ||
} | ||
|
||
_lastThingStatus = status; | ||
_lastThingStatusDetail = detail; | ||
} finally { | ||
_statusLock.unlock(); | ||
} | ||
// If we got this far - call the underlying one | ||
_wrappedCallback.statusChanged(status, detail, msg); | ||
|
||
} | ||
|
||
/** | ||
* Overrides the state changed to determine if the state is new or changed and then | ||
* to call the {@link #_wrappedCallback} if it has | ||
* | ||
* @param channelId the channel id that changed | ||
* @param state the new state | ||
*/ | ||
@Override | ||
public void stateChanged(String channelId, State state) { | ||
if (StringUtils.isEmpty(channelId)) { | ||
return; | ||
} | ||
|
||
final State oldState = _state.get(channelId); | ||
|
||
// If both null OR the same value (enums), nothing changed | ||
if (oldState == state) { | ||
return; | ||
} | ||
|
||
// If they are equal - nothing changed | ||
if (oldState != null && oldState.equals(state)) { | ||
return; | ||
} | ||
|
||
// Something changed - save the new state and call the underlying wrapped | ||
_state.put(channelId, state); | ||
_wrappedCallback.stateChanged(channelId, state); | ||
|
||
} | ||
|
||
/** | ||
* Removes the state associated with the channel id. If the channelid | ||
* doesn't exist (or is null or is empty), this method will do nothing. | ||
* | ||
* @param channelId the channel id to remove state | ||
*/ | ||
public void removeState(String channelId) { | ||
if (StringUtils.isEmpty(channelId)) { | ||
return; | ||
} | ||
_state.remove(channelId); | ||
} | ||
|
||
/** | ||
* Overrides the set property to simply call the {@link #_wrappedCallback} | ||
* | ||
* @param propertyName a non-null, non-empty property name | ||
* @param propertyValue a non-null, possibly empty property value | ||
*/ | ||
@Override | ||
public void setProperty(String propertyName, String propertyValue) { | ||
_wrappedCallback.setProperty(propertyName, propertyValue); | ||
|
||
} | ||
} |
Oops, something went wrong.