/**
* C-Nery - A home automation web application for C-Bus.
* Copyright (C) 2008,2009,2012 Dave Oxley <dave@daveoxley.co.uk>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.daveoxley.cnery.scenes;
import com.daveoxley.cnery.entities.Scene;
import com.daveoxley.cnery.entities.SceneActivation;
import com.daveoxley.cbus.CGateException;
import com.daveoxley.cnery.dao.SceneActionDAO;
import com.daveoxley.cnery.dao.SceneActivationDAO;
import com.daveoxley.cnery.entities.SceneAction;
import com.workplacesystems.queuj.Process;
import java.io.Serializable;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.async.Asynchronous;
/**
*
* @author Dave Oxley <dave@daveoxley.co.uk>
*/
class ProcessStatusChange extends Asynchronous {
private final static Log log = LogFactory.getLog(ProcessStatusChange.class);
public void execute(Object timer, final String status_change) {
(new ContextualAsynchronousRequest(timer) {
@Override
protected void process() {
ProcessStatusChangeImpl process = (ProcessStatusChangeImpl)Component.getInstance(ProcessStatusChangeImpl.class);
process.doProcess(status_change);
}
}).run();
}
@Override
public void execute(Object arg0) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void handleException(Exception exception, Object timer) {}
@Name("processStatusChange")
@Scope(ScopeType.EVENT)
public static class ProcessStatusChangeImpl implements Serializable {
private final ProcessSceneImpl SceneAsync = new ProcessSceneImpl();
private final ProcessSceneActionImpl sceneActionAsync = new ProcessSceneActionImpl();
@In
private SceneActivationDAO sceneActivationDAO;
@In
private SceneActionDAO sceneActionDAO;
@In
private GCMGroupListener gcmGroupListener;
public void doProcess(String status_change) {
String status_array[] = status_change.split(" ");
/*if (!status_array[0].equals("lighting"))
return;*/
final String function = status_array[1];
String address = status_array[2];
for (final SceneActivation sceneActivation : sceneActivationDAO.findSceneActivationsByGroupAddress(address)) {
final Scene scene = sceneActivation.getScene();
log.debug("Starting thread for scene " + scene.getName());
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
SceneAsync.execute(null, function, scene, sceneActivation);
}
});
thread.start();
}
for (final SceneAction sceneAction : sceneActionDAO.findSceneActionsByDependGroup(address)) {
final Scene scene = sceneAction.getScene();
log.debug("Starting thread for scene action " + address);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
sceneActionAsync.execute(null, scene, sceneAction);
}
});
thread.start();
}
gcmGroupListener.processStatusChange(status_change);
}
private void attachAndStartProcess(Process<Integer> process) throws CGateException {
if (process.isRunning()) {
process.attach();
if (process.isFailed())
throw new CGateException("Process failed");
}
process.startNow();
}
private class ProcessSceneImpl extends Asynchronous {
public void execute(Object timer, final String function, final Scene scene, final SceneActivation sceneActivation) {
(new ContextualAsynchronousRequest(timer) {
@Override
protected void process() {
log.debug("Running thread for scene " + scene.getName());
try {
Process<Integer> activateProcess = scene.getActivateProcess();
Process<Integer> deactivateProcess = scene.getDeactivateProcess();
if (function.equals("on") || function.equals("ramp")) {
if (sceneActivation.getGroupOnAction() == SceneActivation.Action.ACTIVATE_SCENE)
attachAndStartProcess(activateProcess);
else if (sceneActivation.getGroupOnAction() == SceneActivation.Action.RESET_SCENE)
if (deactivateProcess != null) attachAndStartProcess(deactivateProcess);
}
else {
if (sceneActivation.getGroupOffAction() == SceneActivation.Action.ACTIVATE_SCENE)
attachAndStartProcess(activateProcess);
else if (sceneActivation.getGroupOffAction() == SceneActivation.Action.RESET_SCENE)
if (deactivateProcess != null) attachAndStartProcess(deactivateProcess);
}
}
catch (Exception e) {
new CGateException(e);
}
}
}).run();
}
@Override
public void execute(Object timer) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void handleException(Exception exception, Object timer) {}
};
private class ProcessSceneActionImpl extends Asynchronous {
public void execute(Object timer, final Scene scene, final SceneAction sceneAction) {
(new ContextualAsynchronousRequest(timer) {
@Override
protected void process() {
try {
if (!scene.isActive() &&
!scene.getActivateProcess().isRunning() &&
!scene.getActivateProcess().isWaitingToRun())
return;
Process<Integer> process = sceneAction.getProcess();
if (sceneAction.isFirstRun() &&
!process.isRunning())
return;
attachAndStartProcess(process);
}
catch (Exception e) {
new CGateException(e);
}
}
}).run();
}
@Override
public void execute(Object timer) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void handleException(Exception exception, Object timer) {}
};
}
}