/*******************************************************************************
* ALMA - Atacama Large Millimiter Array
* (c) European Southern Observatory, 2002
* Copyright by ESO (in the framework of the ALMA collaboration)
* and Cosylab 2002, All rights reserved
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package alma.PS;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import alma.ACS.CBDescIn;
import alma.ACS.CBvoid;
import alma.ACS.impl.CharacteristicComponentImpl;
import alma.ACSErr.CompletionHolder;
import alma.ACS.ROdouble;
import alma.ACS.ROdoubleHelper;
import alma.ACS.impl.ROdoubleImpl;
import alma.ACS.ROdoublePOATie;
import alma.ACS.ROpattern;
import alma.ACS.ROpatternHelper;
import alma.ACS.impl.ROpatternImpl;
import alma.ACS.ROpatternPOATie;
import alma.ACS.RWdouble;
import alma.ACS.RWdoubleHelper;
import alma.ACS.impl.RWdoubleImpl;
import alma.ACS.RWdoublePOATie;
import alma.ACS.jbaci.DataAccess;
import alma.ACS.jbaci.DataAccessSupport;
import alma.ACS.jbaci.MemoryDataAccess;
import alma.ACS.jbaci.ReflectionBACIAction;
import alma.ACSErrTypeCommon.wrappers.AcsJCouldntPerformActionEx;
import alma.acs.component.ComponentLifecycleException;
import alma.acs.container.ContainerServices;
import alma.acs.exceptions.AcsJException;
/**
* Implementation of <code>alma.PS.PowerSupply</code>.
* @author <a href="mailto:matej.sekoranjaATcosylab.com">Matej Sekoranja</a>
* @version $id$
*/
public class PowerSupplyImpl extends CharacteristicComponentImpl
implements PowerSupplyOperations {
/**
* Readback property.
*/
protected ROdouble readback;
/**
* Current property.
*/
protected RWdouble current;
/**
* Status property.
*/
protected ROpattern status;
/**
* @see alma.acs.component.ComponentLifecycle#initialize(alma.acs.container.ContainerServices)
*/
public void initialize(ContainerServices containerServices)
throws ComponentLifecycleException {
super.initialize(containerServices);
try
{
// readback/current
DataAccess currentDataAccess = new MemoryDataAccess();
DataAccess readbackDataAccess = new ReadbackDataAccess(currentDataAccess, 10.0);
// current
RWdoubleImpl currentImpl = new RWdoubleImpl("current", this, currentDataAccess);
RWdoublePOATie currentTie = new RWdoublePOATie(currentImpl);
current = RWdoubleHelper.narrow(this.registerProperty(currentImpl, currentTie));
// readback
ROdoubleImpl readbackImpl = new ROdoubleImpl("readback", this, readbackDataAccess);
ROdoublePOATie readbackTie = new ROdoublePOATie(readbackImpl);
readback = ROdoubleHelper.narrow(this.registerProperty(readbackImpl, readbackTie));
// status
ROpatternImpl statusImpl = new ROpatternImpl("status", this, new StatusDataAccess());
ROpatternPOATie statusTie = new ROpatternPOATie(statusImpl);
status = ROpatternHelper.narrow(this.registerProperty(statusImpl, statusTie));
}
catch (Throwable th)
{
throw new ComponentLifecycleException("Failed to create properties.", th);
}
}
/*********************** [ PowerSupply ] ***********************/
/**
* @see alma.PS.PowerSupplyOperations#current()
*/
public RWdouble current() {
return current;
}
/**
* @see alma.PS.PowerSupplyOperations#status()
*/
public ROpattern status() {
return status;
}
/**
* @see alma.PS.PowerSupplyOperations#readback()
*/
public ROdouble readback() {
return readback;
}
/**
* @see alma.PS.PowerSupplyOperations#on(alma.ACS.CBvoid, alma.ACS.CBDescIn)
*/
public void on(CBvoid callback, CBDescIn desc) {
new ReflectionBACIAction(this, this, getClass(), "onImpl", callback, desc).submit();
}
/**
* @see alma.PS.PowerSupplyOperations#off(alma.ACS.CBvoid, alma.ACS.CBDescIn)
*/
public void off(CBvoid callback, CBDescIn desc) {
new ReflectionBACIAction(this, this, getClass(), "offImpl", callback, desc).submit();
}
/**
* @see alma.PS.PowerSupplyOperations#reset(alma.ACS.CBvoid, alma.ACS.CBDescIn)
*/
public void reset(CBvoid callback, CBDescIn desc) {
new ReflectionBACIAction(this, this, getClass(), "resetImpl", callback, desc).submit();
}
/******************* [ Implementations of actions ] *******************/
/**
* On/off state.
*/
protected AtomicBoolean onState = new AtomicBoolean(false);
/**
* Implementation of 'on' method.
* @throws ACS exception on any failure.
*/
public synchronized void onImpl() throws AcsJException
{
if (onState.getAndSet(true) == true)
throw new AcsJCouldntPerformActionEx("Already 'on'.");
}
/**
* Implementation of 'off' method.
* @throws ACS exception on any failure.
*/
public synchronized void offImpl() throws AcsJException
{
if (onState.getAndSet(false) == false)
throw new AcsJCouldntPerformActionEx("Already 'off'.");
}
/**
* Implementation of 'reset' method.
* @throws ACS exception on any failure.
*/
public void resetImpl() throws AcsJException
{
if (onState.get() == false)
throw new AcsJCouldntPerformActionEx("In 'off' state.");
}
/******************* [ DataAccess implementations ] *******************/
/**
* Status property data access - on/off status implemented.
*/
protected class StatusDataAccess extends DataAccessSupport
{
/**
* @see alma.ACS.jbaci.DataAccess#initializeValue()
*/
public boolean initializeValue() {
return false;
}
/**
* @see alma.ACS.jbaci.DataAccess#get(alma.ACSErr.CompletionHolder)
*/
public Object get(CompletionHolder completionHolder)
throws AcsJException {
return new Integer(onState.get() ? 1 : 0);
}
/**
* @see alma.ACS.jbaci.DataAccess#set(java.lang.Object, alma.ACSErr.CompletionHolder)
*/
public void set(Object value, CompletionHolder completion)
throws AcsJException {
if ((((Integer)value).intValue() % 2) == 1)
onImpl();
else
offImpl();
// TODO no notify here...
}
}
/**
* Implementation of readback data access (adds some random noise and responds to on/off status).
*/
protected class ReadbackDataAccess implements DataAccess
{
/**
* Current signal.
*/
protected DataAccess current;
/**
* Noise amplitude.
*/
protected double amplitude;
/**
* Noise random generator.
*/
protected Random noise = new Random();
/**
* Last value (used to achieve nice stepping).
*/
protected double lastValue = 0;
/**
* Constructor.
* @param current current signal (<code>DataAccess</code>).
*/
public ReadbackDataAccess(DataAccess current, double amplitude)
{
this.current = current;
this.amplitude = amplitude;
}
/**
* @see alma.ACS.jbaci.DataAccess#addValueChangeListener(alma.ACS.jbaci.DataAccess.ValueChangeListener)
*/
public void addValueChangeListener(ValueChangeListener listener)
throws OnChangeNotSupportedException {
// we do not support on-change notifications,
// as default implementation of MemoryDataAccess does
// but can be done simply by registering ValueChangeListener on sourceSignals
// recommend 1s pooling
throw new OnChangeNotSupportedException(1000);
}
/**
* @see alma.ACS.jbaci.DataAccess#removeValueChangeListener(alma.ACS.jbaci.DataAccess.ValueChangeListener)
*/
public void removeValueChangeListener(ValueChangeListener listener) {
// noop
}
/**
* @see alma.ACS.jbaci.DataAccess#initializeValue()
*/
public boolean initializeValue() {
return false;
}
/**
* @see alma.ACS.jbaci.DataAccess#get(alma.ACSErr.CompletionHolder)
*/
public Object get(CompletionHolder completionHolder)
throws AcsJException {
double val = 0;
// read current only if powersupply is 'on'
if (onState.get())
val = ((Double)current.get(completionHolder)).doubleValue();
// stepping
val = (val + lastValue)/2;
// add some noise
val += - amplitude + 2 * amplitude * noise.nextDouble();
val = Math.abs(val);
lastValue = val;
// only positive readback please
return new Double(val);
}
/**
* @see alma.ACS.jbaci.DataAccess#set(java.lang.Object, alma.ACSErr.CompletionHolder)
*/
public void set(Object value, CompletionHolder completion)
throws AcsJException {
throw new AcsJCouldntPerformActionEx("'readback' cannot be set.");
}
}
}