Building Controls Virtual Test Bed
ADInterfaceMCC.java
Go to the documentation of this file.
1 /* A base class for the ADInterfaceMCC reader and ADInterfaceMCC writer.
2 
3 Copyright Notice
4 ----------------
5 
6 Building Controls Virtual Test Bed (BCVTB) Copyright (c) 2008-2009, The
7 Regents of the University of California, through Lawrence Berkeley
8 National Laboratory (subject to receipt of any required approvals from
9 the U.S. Dept. of Energy). All rights reserved.
10 
11 If you have questions about your rights to use or distribute this
12 software, please contact Berkeley Lab's Technology Transfer Department
13 at TTD@lbl.gov
14 
15 NOTICE. This software was developed under partial funding from the U.S.
16 Department of Energy. As such, the U.S. Government has been granted for
17 itself and others acting on its behalf a paid-up, nonexclusive,
18 irrevocable, worldwide license in the Software to reproduce, prepare
19 derivative works, and perform publicly and display publicly. Beginning
20 five (5) years after the date permission to assert copyright is obtained
21 from the U.S. Department of Energy, and subject to any subsequent five
22 (5) year renewals, the U.S. Government is granted for itself and others
23 acting on its behalf a paid-up, nonexclusive, irrevocable, worldwide
24 license in the Software to reproduce, prepare derivative works,
25 distribute copies to the public, perform publicly and display publicly,
26 and to permit others to do so.
27 
28 
29 Modified BSD License agreement
30 ------------------------------
31 
32 Building Controls Virtual Test Bed (BCVTB) Copyright (c) 2008-2009, The
33 Regents of the University of California, through Lawrence Berkeley
34 National Laboratory (subject to receipt of any required approvals from
35 the U.S. Dept. of Energy). All rights reserved.
36 
37 Redistribution and use in source and binary forms, with or without
38 modification, are permitted provided that the following conditions are met:
39 
40  1. Redistributions of source code must retain the above copyright
41  notice, this list of conditions and the following disclaimer.
42  2. Redistributions in binary form must reproduce the above copyright
43  notice, this list of conditions and the following disclaimer in
44  the documentation and/or other materials provided with the
45  distribution.
46  3. Neither the name of the University of California, Lawrence
47  Berkeley National Laboratory, U.S. Dept. of Energy nor the names
48  of its contributors may be used to endorse or promote products
49  derived from this software without specific prior written permission.
50 
51 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
52 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
53 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
54 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
55 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
58 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
59 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
60 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 
63 You are under no obligation whatsoever to provide any bug fixes,
64 patches, or upgrades to the features, functionality or performance of
65 the source code ("Enhancements") to anyone; however, if you choose to
66 make your Enhancements available either publicly, or directly to
67 Lawrence Berkeley National Laboratory, without imposing a separate
68 written license agreement for such Enhancements, then you hereby grant
69 the following license: a non-exclusive, royalty-free perpetual license
70 to install, use, modify, prepare derivative works, incorporate into
71 other computer software, distribute, and sublicense such enhancements or
72 derivative works thereof, in binary and source code form.
73 
74 ********************************************************************
75 */
76 package adInterfaceMCC.util;
77 
78 import ptolemy.actor.TypedAtomicActor;
79 import ptolemy.actor.TypedIOPort;
80 import ptolemy.actor.lib.SequenceActor;
81 import ptolemy.data.DoubleToken;
82 import ptolemy.data.IntToken;
83 import ptolemy.data.Token;
84 import ptolemy.data.ArrayToken;
85 import ptolemy.data.expr.Parameter;
86 import ptolemy.data.type.BaseType;
87 import ptolemy.kernel.CompositeEntity;
88 import ptolemy.kernel.util.IllegalActionException;
89 import ptolemy.kernel.util.NameDuplicationException;
90 import ptolemy.data.type.ArrayType;
91 import ptolemy.data.BooleanToken;
92 import ptolemy.data.StringToken;
93 import ptolemy.data.expr.FileParameter;
94 import ptolemy.kernel.util.Workspace;
95 import ptolemy.kernel.util.Attribute;
96 import java.io.File;
97 import java.io.FileNotFoundException;
98 import java.io.IOException;
99 import java.io.BufferedReader;
100 import java.io.InputStreamReader;
101 import java.util.ArrayList;
102 import java.util.Arrays;
103 import org.xml.sax.SAXException;
104 import javax.xml.validation.Schema;
105 import javax.xml.parsers.ParserConfigurationException;
107 
110 
118 public abstract class ADInterfaceMCC extends TypedAtomicActor implements SequenceActor {
129  public ADInterfaceMCC(CompositeEntity container, String name)
130  throws NameDuplicationException, IllegalActionException {
131  super(container, name);
132 
133  /*Use errorSignal port to send error signal
134  */
135  errorSignal = new TypedIOPort(this,"errorSignal",false,true);
136  errorSignal.setTypeEquals(BaseType.INT);
137  /*Use output port to send error message
138  */
139  errorMessage = new TypedIOPort(this, "errorMessage", false, true);
140  errorMessage.setTypeEquals(BaseType.STRING);
141 
142  /* Use consoleArr to send console output
143  */
144  consoleArr = new TypedIOPort(this,"consoleOutput",false,true);
145  consoleArr.setTypeEquals(new ArrayType(BaseType.STRING));
146  /*Parameter setting the path of configuration file
147  */
148  configurationFile = new FileParameter(this, "configurationFile");
149  new Parameter(configurationFile, "allowFiles", BooleanToken.TRUE);
150  new Parameter(configurationFile, "allowDirectories", BooleanToken.FALSE);
151  /*Parameter determine whether throw exception to screen when error happens
152  */
153  continueWhenError = new Parameter(this,"continueWhenError",new BooleanToken(true));
154  continueWhenError.setTypeEquals(BaseType.BOOLEAN);
155  }
156 
165  public Object clone(Workspace workspace) throws CloneNotSupportedException {
166  ADInterfaceMCC newObject = (ADInterfaceMCC) (super.clone(workspace));
167 
168  // set the type constraints
169  newObject.errorMessage.setTypeEquals(BaseType.STRING);
170  newObject.errorSignal.setTypeEquals(BaseType.INT);
171  newObject.consoleArr.setTypeEquals(new ArrayType(BaseType.STRING));
172  newObject.configurationFile = (FileParameter) newObject
173  .getAttribute("configurationFile");
174  newObject.continueWhenError = (Parameter) newObject
175  .getAttribute("continueWhenError");
176  return newObject;
177  }
178 
184  public void attributeChanged(Attribute attribute)
185  throws IllegalActionException {
186  if (attribute == continueWhenError) {
187  _continueWhenError = ((BooleanToken)(continueWhenError.getToken())).booleanValue();
188  } else {
189  super.attributeChanged(attribute);
190  }
191  }
192 
198  protected abstract void setSchemaFileName();
199 
208  public void initialize() throws IllegalActionException
209  {
210  super.initialize();
211  /*Initialize variables
212  */
213  _errsig = 0;
214  _errmsg = "";
215  _firecount = 0;
216 
218 
219  /*check if configuration file exists
220  */
222 
223  /*set configuration file path
224  */
226  /*check if schema file exists
227  */
229 
230  /*check if the operation system is Mac OS X or Linux
231  */
232  checkOperatingSystem();
233 
234  /* Make instance of the ADInterfaceMCC device manager */
236 
237  /*check if the ADInterfaceMCC-stack library has been compiled
238  */
239  checkADInterfaceMCCStackCompilation();
240 
241  /*Validate configuration file syntax
242  */
243  validateSyntax();
244 
245  /*Store data in configuration file to ad_arr
246  */
248 
249  /*Store the device instance array to devins_arr
250  */
251  //devins_arr = readDeviceArray();
252  //nDev = devins_arr.size();
253 
254  /* Read all the properties specified in configuration file,
255  and store it to prop_arr
256  */
257  prop_arr = ad_arr;
258  nPro = prop_arr.size();
259 
260  // Assign storage for arrays
261  propval_arr = new ArrayList<String>(nPro);
262  consout_arr = new ArrayList<String>(nPro);
263  propval_arr_temp = new ArrayList<String>(nPro);
264  new ArrayList<String>(nPro);
265  exitval_arr = new ArrayList<Integer>(nPro);
266 
267  //new ArrayList<Integer>(nDev);
268  }
269 
277  public void checkConfFileExists() throws IllegalActionException
278  {
279  try{
280  final File confile = configurationFile.asFile();
281  //check if file exists
282  if(!confile.exists())
283  throw new IllegalActionException("The configuration file '"
284  + confile.getPath() +
285  "' cannot be found.");
286  }
287  catch(NullPointerException e)
288  {
289  String em;
290  if (e.getMessage() == null)
291  em = "Failed to read configuration file in ADInterfaceMCCReader or ADInterfaceMCCWriter." + LS +
292  "Check parameters of these actors.";
293  else
294  em = e.getMessage();
295  throw new IllegalActionException(em);
296  }
297  }
298 
303  public void setConfigurationFilePath() throws IllegalActionException
304  {
305  configurationFilePath = configurationFile.asFile().getPath();
306  }
307 
313  public void checkSchemaFileExists() throws IllegalActionException
314  {
315  File schemaFile = new File(schemaFileName);
316  if(!schemaFile.exists())
317  throw new IllegalActionException("The schema file '" + schemaFileName
318  + "' cannot be found.");
319  }
320 
327  void checkOperatingSystem() throws IllegalActionException
328  {
329  if(osName.startsWith("Mac") || osName.startsWith("Lin") )
330  throw new IllegalActionException( "This program only works on Windows."
331  + LS + "The operating system '" + osName + "' is not supported.");
332  }
333 
341  void checkADInterfaceMCCStackCompilation() throws IllegalActionException
342  {
343  String adrp = adDevMan.getReadPropertyBinaryPath();
344  String adwp = adDevMan.getWritePropertyBinaryPath();
345 
346  File fadrp = new File(adrp);
347  File fadwp = new File(adwp);
348  if(!fadrp.exists() || !fadwp.exists())
349  throw new IllegalActionException
350  ("The ADInterfaceMCC-stack library has not been compiled."
351  + LS + "Please compile it.");
352  }
353 
363  public ArrayList<ADInterfaceMCCObjectType> readXMLConfigurationFile()
364  throws IllegalActionException
365  {
366  ArrayList<ADInterfaceMCCObjectType> confdata = new ArrayList<ADInterfaceMCCObjectType>();
367  try{
368  confdata = adDevMan.parseADInterfaceMCCObjectType(configurationFilePath);
369  }
370  catch(SAXException e)
371  {
372  throw new IllegalActionException(e.getMessage());
373  }
374  catch(ParserConfigurationException e)
375  {
376  throw new IllegalActionException(e.getMessage());
377  }
378  catch(IOException e)
379  {
380  throw new IllegalActionException(e.getMessage());
381  }
382  return confdata;
383  }
388  {
389  Object[] propval_arr_obj = new String[nPro];
390  String[] propval_arr_str = (String[]) propval_arr.toArray(propval_arr_obj);
391  String[] propval_arr_temp_str = new String[propval_arr_obj.length];
392  System.arraycopy(propval_arr_str,0,propval_arr_temp_str,0,nPro);
393  propval_arr_temp = new ArrayList<String>(Arrays.asList(propval_arr_temp_str));
394 
395  Object[] consout_arr_obj = new String[nPro];
396  String[] consout_arr_str = (String[])consout_arr.toArray(consout_arr_obj);
397  String[] consout_arr_temp_str = new String[consout_arr_obj.length];
398  System.arraycopy(consout_arr_str,0,consout_arr_temp_str,0,nPro);
399  new ArrayList<String>(Arrays.asList(consout_arr_temp_str));
400  }
401 
410  private boolean throwExceptions(){
411  return ( (_continueWhenError==false ) || (_firecount == 1 ) );
412  }
413 
423  public void executeProcess(ArrayList<ProcessBuilder> process_arr)
424  throws IllegalActionException
425  {
426  Process p = null;
427  String line = "";
428  String allline = ""; //for all console outputs
429  String infoline = ""; //for only useful information
430  //increase firecount by 1
431  _firecount += 1;
432  //store new values to arraylist
433  for(int i=0;i<process_arr.size();i++){
434  try{
435  p = process_arr.get(i).redirectErrorStream(true).start();
436  }
437  catch(IOException e)
438  {
439  String em = "Error while executing processes."
440  + LS + e.getMessage();
441  _errsig = 1;
442  _errmsg = em;
443  if( throwExceptions() )
444  throw new IllegalActionException(em);
445  }
446  catch(NullPointerException e)
447  {
448  String em = "Some of the command arguments are null."
449  + LS + e.getMessage();
450  _errmsg = em;
451  _errsig = 1;
452  if( throwExceptions() )
453  throw new IllegalActionException(em);
454  }
455  catch(IndexOutOfBoundsException e)
456  {
457  String em = "The process list is empty." +
458  LS + e.getMessage();
459  _errsig = 1;
460  _errmsg = em;
461  if( throwExceptions() )
462  throw new IllegalActionException(em);
463  }
464  catch(SecurityException e)
465  {
466  String em = "Creation of the process is not allowed."
467  + LS + e.getMessage();
468  _errsig = 1;
469  _errmsg = em;
470  if( throwExceptions() )
471  throw new IllegalActionException(em);
472  }
473  BufferedReader br = new BufferedReader(new InputStreamReader
474  (p.getInputStream()));
475  try{
476  while((line=br.readLine())!=null)
477  {
478  allline = allline + line;
479  if(
480  !line.contains("Error") && !line.contains("Invalid")
481  && !line.contains("Note")){
482  // propval_arr.set(i, line);
483  infoline = infoline + line;
484  }
485  else
486  {
487  String em = "The response from ADInterfaceMCC is '" + line + "'." + LS;
488  _errsig = 1;
489  _errmsg += em;
490  if( throwExceptions() )
491  throw new IllegalActionException(em);
492  else{ // use data from last call
493  //set is only used to replace current element
494  // propval_arr.set(i, propval_arr_temp.get(i));
495  propval_arr.add(propval_arr_temp.get(i));
496  }
497  }
498  }
499  }
500  catch(IOException e)
501  {
502  String em = "Error while reading response." +
503  LS + e.getMessage();
504  _errmsg = em;
505  _errsig = 1;
506  if( throwExceptions() )
507  throw new IllegalActionException(em);
508  }
509  try{
510  p.waitFor();
511  }
512  catch(InterruptedException e)
513  {
514  String em = "The process of running adInterfaceMCC stack" + LS
515  + "command has been interrupted" + LS +
516  e.getMessage();
517  _errsig = 1;
518  _errmsg = em;
519  if( throwExceptions() )
520  throw new IllegalActionException(em);
521  }
522  consout_arr.add(allline);
523  allline = "";
524  propval_arr.add(infoline);
525  infoline = "";
526  int exit = p.exitValue();
527  if(exit!=0)
528  {
529  String em = "ADInterfaceMCC-stack process quit abnormally.";
530  _errmsg = em;
531  _errsig = 1;
532  if( throwExceptions() )
533  throw new IllegalActionException(em);
534  }
535  // exitval_arr.set(i, exit);
536  exitval_arr.add(exit);
537  }
538  consout_arr.trimToSize();
539  propval_arr.trimToSize();
540  exitval_arr.trimToSize();
541  }
542 
546  public Token[] transformArrayListString(ArrayList<String> data_str)
547  {
548  Token[] valArray = new Token[data_str.size()];
549  for(int i=0; i<data_str.size(); i++)
550  valArray[i] = new StringToken( data_str.get(i) );
551  return valArray;
552  }
553  public Token[] transformArrayListDouble(ArrayList<String> data_str)
554  {
555  Token[] valArray = new Token[data_str.size()];
556  for(int i=0; i<data_str.size(); i++)
557  valArray[i] = new DoubleToken(Double.valueOf(data_str.get(i)));
558  return valArray;
559  }
568  public void prepareTokensToSend() throws IllegalActionException
569  {
572  //error signal and error message have been handled in
573  //executeprocess
576  }
577 
580 
581 
588  public void sendToken() throws IllegalActionException
589  {
590  errorSignal.send(0,new IntToken(_errsig));
591  errorMessage.send(0,new StringToken(_errmsg));
592  consoleArr.send(0,new ArrayToken(BaseType.STRING,consout_tok));
593  }
594 
606  public void validateAttributes() throws IllegalActionException
607  {
608  for(int i=0; i<ad_arr.size();i++)
609  {
610  String apptag = ad_arr.get(i).getApplicationTag();
611  adDevMan.validateApplicationTag(apptag);
612  }
613  }
614 
620  public void validateSyntax() throws IllegalActionException
621  {
622 
623  try{
624  Schema schema = adDevMan.loadSchema(schemaFileName);
625  adDevMan.validateXMLFile(configurationFilePath,schema);
626  }
627  catch(FileNotFoundException e)
628  {
629  throw new IllegalActionException(e.getMessage());
630  }
631  catch(IOException e)
632  {
633  throw new IllegalActionException(e.getMessage());
634  }
635  catch (SAXException e) {
636  throw new IllegalActionException(e.getMessage());
637  }
638 
639  }
645  public void removeToken() throws IllegalActionException
646  {
647  propval_arr.clear();
648  consout_arr.clear();
649  exitval_arr.clear();
650  }
651 
654 
658  public TypedIOPort errorMessage;
659 
662  public TypedIOPort errorSignal;
663 
666  protected TypedIOPort consoleArr;
667 
670  protected Parameter errorMessage_tokenProductionRate;
671 
675  protected Parameter errorMessage_tokenInitProduction;
676 
679  private int _errsig;
680 
683  private String _errmsg;
684 
686  public Parameter continueWhenError;
687 
689  protected boolean _continueWhenError;
690 
693  public FileParameter configurationFile;
694 
697  protected String configurationFilePath;
698 
701  protected String schemaFileName;
702 
705  private ArrayList<ADInterfaceMCCObjectType> ad_arr;
706 
710  private ArrayList<Integer> devins_arr;
711 
715  protected ArrayList<ADInterfaceMCCObjectType> prop_arr;
716 
719  protected ArrayList<ProcessBuilder> proc_arr;
720 
723  private ArrayList<String> propval_arr;
724 
728  private ArrayList<String> propval_arr_temp;
729 
732  protected Token[] propval_tok;
733 
737  protected ArrayList<String> consout_arr;
738 
740  protected Token[] consout_tok;
741 
743  protected ArrayList<Integer> exitval_arr;
744 
746  private int _firecount;
747 
749  public final static String FS = System.getProperty("file.separator");
750 
752  public final static String LS = System.getProperty("line.separator");
753 
755  public final static String bcvtbhome = System.getenv("BCVTB_HOME");
756 
758  public final static String osName= System.getProperty("os.name");
759 
762 
764  private int nDev;
766  private int nPro;
767 }
ArrayList< ADInterfaceMCCObjectType > readXMLConfigurationFile()
Read the xml configuration file, store the elements to ADInterfaceMCCObjectType ArrayList.
for i
Definition: compile.m:69
static final String bcvtbhome
String that points to root directory of the BCVTB.
ArrayList< ProcessBuilder > proc_arr
Arraylist containing processes to be executed in console.
void prepareTokensToSend()
Get tokens to send for the next timestep.
ArrayList< Integer > devins_arr
ArrayList containing device instance number read from configuration file.
ADInterfaceMCCDeviceManager adDevMan
The ADInterfaceMCC device manager.
ArrayList< String > propval_arr_temp
ArrayList temporarily holding property values read from previous time step.
TypedIOPort consoleArr
The port that send response from console.
TypedIOPort errorSignal
The port that outputs the error signal.
static final String LS
Line Seperator.
ArrayList< ADInterfaceMCCObjectType > ad_arr
ArrayList containing elements read from configuration file.
void validateSyntax()
Validate xml configuration file syntax.
Parameter errorMessage_tokenInitProduction
The rate parameter for the errorMessage port that declares the initial production.
ArrayList< String > propval_arr
ArrayList containing strings of property values read from device.
abstract void setSchemaFileName()
Abstract class that sets the schema file name.
ArrayList< ADInterfaceMCCObjectType > prop_arr
Arraylist containing ADInterfaceMCCObjectType read from configuration file.
Token[] propval_tok
Token array of property values.
String _errmsg
detailed error message
boolean _continueWhenError
Parameter to control whether to continue if there was an error message.
int _errsig
signal to indicate whether there is an error, 0 means right, 1 means wrong
String configurationFilePath
String of configuration file path.
void storeDataInLastTimeStep()
Store response from last time step.
static final String FS
File seperator.
void checkSchemaFileExists()
Check if schema file exists.
void initialize()
Initialization section, initialize variables and check possible errors.
Parameter errorMessage_tokenProductionRate
The rate parameter for the errorMessage port.
boolean throwExceptions()
Returns true if an exception should be thrown, or false if only an error message should be sent to th...
TypedIOPort errorMessage
The errorMessage port.
int nPro
Number of ADInterfaceMCC properties specified in the configuration file.
Parameter continueWhenError
Parameter to control whether to continue if there was an error message.
Object clone(Workspace workspace)
Clone the actor into the specified workspace.
String schemaFileName
Schema file path.
Token[] transformArrayListDouble(ArrayList< String > data_str)
This is the driver class in ADInterfaceMCC.
void checkConfFileExists()
Check if configuration file exists.
void executeProcess(ArrayList< ProcessBuilder > process_arr)
Execute Processes, store results to consoleoutput_arr and exitvalue-arr.
ArrayList< Integer > exitval_arr
ArrayList containing strings process exit values for each process.
void validateAttributes()
Validate application tag.
Token[] transformArrayListString(ArrayList< String > data_str)
Transform String Arraylist to Token Arrays.
Token[] consout_tok
Token array of console outputs.
void setConfigurationFilePath()
Set configuration file path.
FileParameter configurationFile
Parameter to specify the path for configuraton file.
ADInterfaceMCC(CompositeEntity container, String name)
Construct an actor with the given container and name.
void removeToken()
Remove tokens in previous time step.
This is an abstract base class for actors that generates an output stream.
void sendToken()
Sends the error signal to the errorSignal port, the error message to the errorMessage port...
int _firecount
parameter indicate how many times executeProcess function has been run
static final String osName
Name of the operating system.
ArrayList< String > consout_arr
ArrayList containing strings of response from device for ad reading and writing process.
int nDev
Number of ADInterfaceMCC devices specified in the configuration file.
void attributeChanged(Attribute attribute)
Override the base class to determine which argument is being used.