diff --git a/ch.psi.fda/src/main/java/ch/psi/fda/core/actions/ChannelAccessConditionAnd.java b/ch.psi.fda/src/main/java/ch/psi/fda/core/actions/ChannelAccessConditionAnd.java new file mode 100644 index 0000000..3c52821 --- /dev/null +++ b/ch.psi.fda/src/main/java/ch/psi/fda/core/actions/ChannelAccessConditionAnd.java @@ -0,0 +1,155 @@ +/** + * + * Copyright 2010 Paul Scherrer Institute. All rights reserved. + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This code 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + * + */ + +package ch.psi.fda.core.actions; + +import java.util.Comparator; +import java.util.logging.Logger; + +import gov.aps.jca.CAException; +import ch.psi.fda.core.Action; +import ch.psi.jcae.ChannelBean; +import ch.psi.jcae.ChannelBeanFactory; + +/** + * Perform a put on the specified Channel Access channel. The put can be done synchronous or + * asynchronously. + * @author ebner + * + */ +public class ChannelAccessConditionAnd implements Action { + + // Get Logger + private static Logger logger = Logger.getLogger(ChannelAccessConditionAnd.class.getName()); + + /** + * Channel to set + */ + private final ChannelBean channel; + /** + * Value to wait for + */ + private final E expectedValue; + + private final Long timeout; + + private volatile boolean abort = false; + private volatile Thread waitT = null; + + /** + * Constructor + * @param channelName Name of the channel to set the value + * @param expectedValue Value to wait for + * @param timeout Timeout of the condition in milliseconds (null accepted - will take default wait timeout for channels ch.psi.jcae.ChannelBeanFactory.waitTimeout) + * + * @throws IllegalArgumentException Unable to initialize channel, + * Timeout specified is not >=0 + */ + @SuppressWarnings("unchecked") + public ChannelAccessConditionAnd(String channelName, E expectedValue, Long timeout){ + + if(timeout !=null && timeout<=0){ + throw new IllegalArgumentException("Timeout must be > 0"); + } + + try { + this.channel = (ChannelBean) ChannelBeanFactory.getFactory().createChannelBean( (Class) expectedValue.getClass(), channelName, false); + } catch (CAException e) { + // Convert Exception into unchecked RuntimeException + throw new IllegalArgumentException("Unable to initialize actuator channel [name:"+channelName+"]",e); + } catch (InterruptedException e) { + throw new RuntimeException("Unable to initialize actuator channel [name:"+channelName+"]",e); + } + + this.expectedValue = expectedValue; + + if(timeout==null){ + this.timeout = channel.getWaitTimeout(); + } + else{ + this.timeout = timeout; + } + } + + + /* (non-Javadoc) + * @see ch.psi.fda.core.Action#execute() + */ + /** + * @throws InterruptedException + * @throws RuntimeException Channel value did not reach expected value (within the specified timeout period) + */ + @Override + public void execute() throws InterruptedException { + abort=false; + logger.finest("Checking channel "+channel.getName()+" for value "+expectedValue+" [timeout: "+timeout+"]" ); + try{ + waitT = Thread.currentThread(); + channel.waitForValue(expectedValue, new Comparator() { + + @Override + public int compare(E o1, E o2) { + int one = o1; + int two = o2; + if((one & two) != 0){ + return 0; + } + return 1; + } + } + , timeout); // Workaround use 10seconds default set timeout to check several times whether the channel has reached the value + } catch (CAException e) { + throw new RuntimeException("Channel [name:"+channel.getName()+"] did not reach expected value "+expectedValue+" ", e); + } catch(InterruptedException e){ + if(!abort){ + throw e; + } + } + finally{ + waitT=null; + } + } + + /* (non-Javadoc) + * @see ch.psi.fda.core.Action#abort() + */ + @Override + public void abort() { + abort=true; + if(waitT!=null){ + waitT.interrupt(); + } + } + + + /* (non-Javadoc) + * @see ch.psi.fda.core.Action#destroy() + */ + @Override + public void destroy() { + // Destroy channel + try { + logger.finest("Destroy action channel: "+channel.getName()); + channel.destroy(); + } catch (CAException e) { + throw new RuntimeException("Unable to destroy channel ["+channel.getName()+"]",e); + } + } + +} diff --git a/ch.psi.fda/src/main/java/ch/psi/fda/core/actions/ChannelAccessConditionOr.java b/ch.psi.fda/src/main/java/ch/psi/fda/core/actions/ChannelAccessConditionOr.java new file mode 100644 index 0000000..b4ca64b --- /dev/null +++ b/ch.psi.fda/src/main/java/ch/psi/fda/core/actions/ChannelAccessConditionOr.java @@ -0,0 +1,155 @@ +/** + * + * Copyright 2010 Paul Scherrer Institute. All rights reserved. + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This code 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + * + */ + +package ch.psi.fda.core.actions; + +import java.util.Comparator; +import java.util.logging.Logger; + +import gov.aps.jca.CAException; +import ch.psi.fda.core.Action; +import ch.psi.jcae.ChannelBean; +import ch.psi.jcae.ChannelBeanFactory; + +/** + * Perform a put on the specified Channel Access channel. The put can be done synchronous or + * asynchronously. + * @author ebner + * + */ +public class ChannelAccessConditionOr implements Action { + + // Get Logger + private static Logger logger = Logger.getLogger(ChannelAccessConditionOr.class.getName()); + + /** + * Channel to set + */ + private final ChannelBean channel; + /** + * Value to wait for + */ + private final E expectedValue; + + private final Long timeout; + + private volatile boolean abort = false; + private volatile Thread waitT = null; + + /** + * Constructor + * @param channelName Name of the channel to set the value + * @param expectedValue Value to wait for + * @param timeout Timeout of the condition in milliseconds (null accepted - will take default wait timeout for channels ch.psi.jcae.ChannelBeanFactory.waitTimeout) + * + * @throws IllegalArgumentException Unable to initialize channel, + * Timeout specified is not >=0 + */ + @SuppressWarnings("unchecked") + public ChannelAccessConditionOr(String channelName, E expectedValue, Long timeout){ + + if(timeout !=null && timeout<=0){ + throw new IllegalArgumentException("Timeout must be > 0"); + } + + try { + this.channel = (ChannelBean) ChannelBeanFactory.getFactory().createChannelBean( (Class) expectedValue.getClass(), channelName, false); + } catch (CAException e) { + // Convert Exception into unchecked RuntimeException + throw new IllegalArgumentException("Unable to initialize actuator channel [name:"+channelName+"]",e); + } catch (InterruptedException e) { + throw new RuntimeException("Unable to initialize actuator channel [name:"+channelName+"]",e); + } + + this.expectedValue = expectedValue; + + if(timeout==null){ + this.timeout = channel.getWaitTimeout(); + } + else{ + this.timeout = timeout; + } + } + + + /* (non-Javadoc) + * @see ch.psi.fda.core.Action#execute() + */ + /** + * @throws InterruptedException + * @throws RuntimeException Channel value did not reach expected value (within the specified timeout period) + */ + @Override + public void execute() throws InterruptedException { + abort=false; + logger.finest("Checking channel "+channel.getName()+" for value "+expectedValue+" [timeout: "+timeout+"]" ); + try{ + waitT = Thread.currentThread(); + channel.waitForValue(expectedValue, new Comparator() { + + @Override + public int compare(E o1, E o2) { + int one = o1; + int two = o2; + if((one | two) != 0){ + return 0; + } + return 1; + } + } + , timeout); // Workaround use 10seconds default set timeout to check several times whether the channel has reached the value + } catch (CAException e) { + throw new RuntimeException("Channel [name:"+channel.getName()+"] did not reach expected value "+expectedValue+" ", e); + } catch(InterruptedException e){ + if(!abort){ + throw e; + } + } + finally{ + waitT=null; + } + } + + /* (non-Javadoc) + * @see ch.psi.fda.core.Action#abort() + */ + @Override + public void abort() { + abort=true; + if(waitT!=null){ + waitT.interrupt(); + } + } + + + /* (non-Javadoc) + * @see ch.psi.fda.core.Action#destroy() + */ + @Override + public void destroy() { + // Destroy channel + try { + logger.finest("Destroy action channel: "+channel.getName()); + channel.destroy(); + } catch (CAException e) { + throw new RuntimeException("Unable to destroy channel ["+channel.getName()+"]",e); + } + } + +}