/** * 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) {} }; } }