ALMA Computing Group

acsexmplClientAlarmThread.cpp

Go to the documentation of this file.
00001 /******************************************************************************* 00002 * ALMA - Atacama Large Millimiter Array 00003 * (c) European Southern Observatory, 2002 00004 * Copyright by ESO (in the framework of the ALMA collaboration) 00005 * and Cosylab 2002, All rights reserved 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 * 00021 * 00022 * 00023 * "@(#) $Id: acsexmplClientAlarmThread.cpp,v 1.109 2007/02/01 05:14:26 cparedes Exp $" 00024 * 00025 * who when what 00026 * -------- -------- ---------------------------------------------- 00027 * david 2002-09-04 added ACE_TRY_CHECK on line 171 to get rid of warnings. 00028 * david 2002-06-17 fixed client.init(argc,argv) 00029 * naoj 2002-03-12 Added implementation of spawning thread in which value changes of current simulated 00030 * gchiozzi 2002-02-13 Cleaned up and renamed 00031 * gchiozzi 2002-01-23 Removed #define _POSIX_SOURCE 1. Gives problems on Solaris. 00032 * almamgr 2002-01-22 Replaced old include files with new axsexmpl... files 00033 * gchiozzi 2001-02-15 Merged: added tests for IFR and history. 00034 * gchiozzi 2001-02-15 created standard header 00035 * msekoran 2001-03-14 Changed namespace ESO to ACS 00036 * msekoran 2001-03-20 Added Alarmdouble (event) example 00037 */ 00038 00062 00067 00100 /* @}*/ 00101 /* @}*/ 00102 #include <maciSimpleClient.h> 00103 #include <acsThread.h> 00104 #include "acsexmplCallbacks.h" 00105 00106 #include <acsexmplPowerSupplyC.h> 00107 00108 ACE_RCSID(acsexmpl, acsexmplClientAlarmThread, "$Id: acsexmplClientAlarmThread.cpp,v 1.109 2007/02/01 05:14:26 cparedes Exp $") 00109 00110 using namespace ACS; 00111 using namespace maci; 00112 00116 class WorkerThread : public ACS::Thread 00117 { 00118 public: 00119 WorkerThread(const ACE_CString& name, 00120 ACS::RWdouble_var curr, 00121 const ACS::TimeInterval& responseTime=ThreadBase::defaultResponseTime, 00122 const ACS::TimeInterval& sleepTime=ThreadBase::defaultSleepTime) : 00123 ACS::Thread(name, responseTime, sleepTime) 00124 { 00125 ACS_TRACE("WorkerThread::WorkerThread"); 00126 current = curr; 00127 count = 0; 00128 numValues = 7; 00129 values = new double[7]; 00130 values[0] = 50; 00131 values[1] = 8; 00132 values[2] = 15; 00133 values[3] = 25; 00134 values[4] = 995; 00135 values[5] = 970; 00136 values[6] = 50; 00137 00138 ACS_SHORT_LOG((LM_INFO, "%s: Created thread", getName().c_str())); 00139 } 00140 00141 ~WorkerThread() 00142 { 00143 ACS_TRACE("WorkerThread::~WorkerThread"); 00144 if(NULL != values) 00145 { 00146 delete[] values; 00147 } 00148 } 00149 00150 virtual void runLoop() 00151 { 00152 if(0 == count) { 00153 ACS_SHORT_LOG((LM_INFO, "%s: Started runLoop for thread", getName().c_str())); 00154 } 00155 //while there are still values that need to be set... 00156 if(count < numValues) 00157 { 00158 try 00159 { 00160 //change the BACI property's value synchronously 00161 ACS_SHORT_LOG((LM_INFO, "%s: Setting current to %f", getName().c_str(), values[count])); 00162 current->set_sync(values[count]); 00163 count++; 00164 } 00165 catch(...) 00166 { 00167 ACS_SHORT_LOG((LM_ERROR,"Error!")); 00168 } 00169 } 00170 else { 00171 setStopped(); 00172 ACS_SHORT_LOG((LM_INFO, "%s: Stopped thread", getName().c_str())); 00173 } 00174 } 00175 00176 private: 00177 ACS::RWdouble_var current; 00178 int count; 00179 int numValues; 00180 //Ranges in the CDB for readback are: 00181 // alarm low on : 10 00182 // alarm low off: 20 00183 // alarm high off: 980 00184 // alarm high on : 990 00185 double * values; 00186 }; 00187 00188 /*-----------------------------------------------------------------*/ 00189 //Now onto the real example... 00192 int main(int argc, char *argv[]) 00193 { 00194 //Checks command-line arguments. 00195 if (argc < 2) 00196 { 00197 ACS_SHORT_LOG((LM_INFO, "Usage: %s <component name> <options>", argv[0])); 00198 return -1; 00199 } 00200 else 00201 { 00202 ACS_SHORT_LOG((LM_INFO, "Welcome to %s!", argv[0])); 00203 } 00204 00205 //Creates and initializes the SimpleClient object 00206 SimpleClient client; 00207 if (client.init(argc,argv) == 0) 00208 { 00209 ACE_DEBUG((LM_DEBUG,"Cannot init client")); 00210 return -1; 00211 } 00212 else 00213 { 00214 //Must log into manager before we can really do anything 00215 client.login(); 00216 } 00217 00218 try 00219 { 00220 //Get reference to the component 00221 ACS_SHORT_LOG((LM_INFO, "Getting component: %s", argv[1])); 00222 PS::PowerSupply_var ps = client.getComponent<PS::PowerSupply>(argv[1],0,true); 00223 if (CORBA::is_nil(ps.in()) == true) 00224 { 00225 ACS_SHORT_LOG((LM_INFO, "Failed to get a reference to the PowerSupply component.")); 00226 return -1; 00227 } 00228 ACS_SHORT_LOG((LM_INFO, "PowerSupply reference retrieved.")); 00229 00230 // first, set the current to a value which won't generate an alarm when 00231 // we first add the alarm subscription. (The CDB schema for the power supply 00232 // defines the conditions under which an alarm will occur.) 00233 ps->current()->set_sync(50); 00234 00235 //Get the BACI property we'll create an alarm for 00236 ACS_SHORT_LOG((LM_INFO, "Trying to get readback... ")); 00237 ACS::ROdouble_var readback = ps->readback(); 00238 ACS_SHORT_LOG((LM_INFO, "OK")); 00239 00240 //create an instance of our alarm class 00241 MyAlarmdouble macb("readback"); 00242 //activate it as a CORBA object 00243 ACS::Alarmdouble_var acb = macb._this(); 00244 //create the actual BACI double alarm 00245 ACS::CBDescIn desc; 00246 ACS::Subscription_var alarmSub = readback->new_subscription_Alarm (acb.in(), desc); 00247 ACS_SHORT_LOG((LM_INFO,"Alarm subscription created")); 00248 00249 ACS::RWdouble_var current = ps->current(); 00250 // create the thread 00251 WorkerThread thread_p /*threadManager.create<WorkerThread,ACS::RWdouble_var>*/ ("actionThread", current, ThreadBase::defaultResponseTime, ThreadBase::defaultSleepTime*10 /*=1s*/); 00252 // by default threads that are not created using a thread manager are creatd suspended so we have to resume them!! 00253 thread_p.resume(); 00254 00255 //Enter main loop and stays there for a fixed amount of time. Really we are 00256 //just allowing the thread we just created to run for awhile before exiting out 00257 //of this example. 00258 ACS_SHORT_LOG((LM_INFO, "(BACIClient main thread) Going in main loop sleep...")); 00259 ACE_Time_Value tv(20); 00260 client.run(tv); 00261 00262 //Must cleanly destroy the alarm 00263 ACS_SHORT_LOG((LM_INFO,"Alarm subscription deleted")); 00264 alarmSub->destroy(); 00265 } 00266 catch(maciErrType::CannotGetComponentExImpl &_ex) 00267 { 00268 _ex.log(); 00269 return -1; 00270 } 00271 catch(...) 00272 { 00273 ACS_SHORT_LOG((LM_ERROR,"Error!")); 00274 return -1; 00275 } 00276 00277 //Another try section where we release our component and logout from manager 00278 try 00279 { 00280 ACS_SHORT_LOG((LM_INFO,"Releasing...")); 00281 client.releaseComponent( argv[1]); 00282 client.logout(); 00283 } 00284 catch(maciErrType::CannotReleaseComponentExImpl &_ex) 00285 { 00286 _ex.log(); 00287 return -1; 00288 } 00289 catch(...) 00290 { 00291 ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__, 00292 "main"); 00293 uex.log(); 00294 return -1; 00295 }//try-catch 00296 00297 //sleep for 3 sec to allow everytihng to cleanup and stabilize 00298 //so that the tests can be determinitstic. 00299 ACE_OS::sleep(3); 00300 return 0; 00301 }