Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Device properties have one of the following scalar types (This list of types was extracted from ACS/LGPL/CommonSoftware/baciidl/ws/idl/baci.idl in ALMA-RELEASE-B branch of Subversion revision 242801): *float{*}, *double{*}, *long* (32-bit signed integer), *uLong* (32-bit unsigned integer), *longLong* (64-bit signed integer), *uLongLong* (64-bit unsigned integer), *boolean{*}, *string{*}, *pattern* and  enum, where "pattern" stands for an unsigned long. The typedef pattern is used because this type will mostly be used to encode a pattern of status bits. Furthermore, "pattern" is a single word as opposed to "unsigned long". The type pattern can be used also for raw binary data. In the next generation of ACS we plan to use code generators, either from a special template preprocessor or from UML models. ThenIn then, it will be much easier to add any new type, therefore it doesn't make much sense to spend the time now.QUESTION: What is the current situation? I would like to make this sentence up-to-date. Or, maybe this sentence can be simply removed because how each type is implemented is irrelevant to, at least, client developers.

Wiki Markup
Several values of the same type are stored as a sequence, according to the IDL type definition, e.g.:
typedef sequence<double> doubleSeq;
\\
Such sequences are already provided by acscommon.idl. Sequences are used when multiple devices are controlled with one method call or when a history of values of one property is requested. The use of sequences for individual values is possible but strongly discouraged, as properties are supposed to be simple objects related to one I/O channel.
The only Component properties with sequences of value types are *floatSeq* (RO and RW), *doubleSeq* (RO and RW), *longSeq* (RO and RW), *uLongSeq* (RO and RW), *boolean* (RO and RW) and *ROstringSeq* (RO only)  This list of types was extracted from ACS/LGPL/CommonSoftware/baciidl/ws/idl/baci.idl in ALMA-RELEASE-B branch of Subversion revision 242801., because others have not been requested. But they can be added at any moment. The same argument as in the paragraph above holds here, too. 
Each value read from the control system has an associated time-stamp. The time should be ideally represented by the CORBA time service through the UTO interface (which is not the POSIX time). As the time service is not yet part of most of the ORBs and the astronomers have other requirements on time, we use a different interface. We use the following definitions for Time and TimeInterval:
typedef unsigned long long Time;
\\
where Time is the absolute time in 100 ns since 1582-10-15 00:00:00QUESTION: I couldn't find any definition of timezone. Does ALMA assume a specific timezone for Time type?, see \[2\]. And
typedef unsigned long long TimeInterval;
\\
where TimeInterval is used for the difference between two absolute time points.
For each operation (action, command, monitor or alarm event), the time stamps, errors and alarm codes are returned through the interface Completion, which is defined as:
\\
\\
struct Completion \{
\\
 unsigned long long timeStamp;  // time stamp in 100th of nsQUESTION: What timestamp is it? Is it the time the hardware provides? Or, is it the time that the device server (or BACI property) calls the callback?
 \\
 ACSErr::ACSErrType type;  // error type (group)
 \\
 ACSErr::ErrorCode code; // error code
 \\
 sequence<ACSErr::ErrorTrace, 1> previousError;   // previos error(s) (error trace)
\\
\}; 
\\
The completion structure is described in more detail in the BACI\[1\] and the ACS Error System Architecture \[3\] documentsTODO: check out this document and learn how previoussError field shall be filled.. Here, we will discuss the basic concepts. When there was no error, struct Completion contains the timestamp, the non-error type (ACSErrTypeOK) and code (ACSErrOK) and an empty previousError (error trace). BACI does not define values of the completion code, because it is open to particular implementations.
When there is an error, completion returns information that allows to pinpoint the reasons; previousError data structure contains detailed information about the error, either used to display or log the information - see the documents on error handling \[3\] and logging \[4\] for more.
\\
Listing 1: Definition of  ACSErrType  extracetd by acserr.idl.
#ifndef _ACSERR_IDL_
#define _ACSERR_IDL_
\\
#pragma prefix "alma"
\\
module ACSErr \{
\\
...
\\
    typedef unsigned long ACSErrType;
    typedef unsigned long ErrorCode;
\\
...
\\
\};
\\
#endif
\\
Error types and their corresponding codes are defined in XML files. For each error type, a unique XML file must be defined by the developer. The type ACSErrTypeMonitor is reserved for monitor callbacks that can be either time or value triggered.
\\
Listing 2: The XML for ACSErrTypeMonitor (ACSErrTypeMonitor.xml).
<?xml version="1.0" encoding="UTF-8"?>
 <Type xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ACSError.xsd" name="ACSErrTypeMonitor" 
type="1" _prefix="alma">
 <Code name="ACSErrMonitorOnTimer" shortDescription="A regular timer monitor triggered the event." description="A regular timer monitor triggered the event."/>
 <Code name="ACSErrMonitorOnValue" shortDescription="The value changed by a specified amount or more." description="The value changed by a specified amount or more."/>
</Type>
\\
Code is automatically generated from the XML file.
Listing 3: Definition of ACS ACSErrTypeMonitor type.
#ifndef  _ACSErrTypeMonitor_IDL_
#define  _ACSErrTypeMonitor_IDL_
\\
#include <acserr.idl>
\\
#pragma prefix "alma"
\\
module ACSErr \{
 // type
 const ACSErr::ACSErrType ACSErrTypeMonitor = 1;
\};
\\
module ACSErrTypeMonitor \{QUESTION: What error type and what error code should be used when BACI property wants to say that it couldn't obtain a valid value from the hardware.
\\
When a new monitor is created, BACI property is obliged to call working() callback method within normal_timeout. It is possible that the hardware cannot respond by the specified time, but BACI property still has to call working() callback method so that the client won't time out. When calling working(), BACI property has to pass some value as the first argument, but that value will be a dummy value (because it is not the value that hardware returns). Thus, BACI property has to tell the client that the value is dummy somehow. Is there a standard way for that? Or, does the device server developer have to define such error code/type for each device?
\\
 //ED: A regular timer monitor triggered the event.
 const ACSErr::ErrorCode ACSErrMonitorOnTimer = 0;
 //ED: The value changed by a specified amount or more.
 const ACSErr::ErrorCode ACSErrMonitorOnValue = 1;
\\
        // exceptions:
\\
\};//module
\\
#endif
\\
The type ACSErrTypeAlarm is reserved for alarm messages that originate from the property value.
 Listing 4: Definition of ACS ACSErrTypeAlarm type.
#ifndef  _ACSErrTypeAlarm_IDL_
#define  _ACSErrTypeAlarm_IDL_
\\
#include <acserr.idl>
\\
#pragma prefix "alma"
\\
module ACSErr \{
 // type
 const ACSErr::ACSErrType ACSErrTypeAlarm = 2;
\};
\\
module ACSErrTypeAlarm \{
\\
 //ED: All alarm conditions have disappeared.
 const ACSErr::ErrorCode ACSErrAlarmCleared = 0;
 //ED: At least one alarm condition remains.
 const ACSErr::ErrorCode ACSErrAlarmChanged = 1;
 //ED: Value below alarm LoLo (includes hysteresis).
 const ACSErr::ErrorCode ACSErrAlarmLow = 2;
 //ED: Value above alarm HiHi (includes hysteresis).
 const ACSErr::ErrorCode ACSErrAlarmHigh = 3;
 //ED: An alarm on the status determined by software.
 const ACSErr::ErrorCode ACSErrAlarmSoftware = 4;
 //ED: An alarm on the status from the hardware.
 const ACSErr::ErrorCode ACSErrAlarmHardware = 5;
\\
        // exceptions:
\\
\};
\\
Alarms as defined above are notifications about the state of the controlled property. Alarms are asynchronous and completely independent events. They have nothing to do with errors that occur during execution flow. In case such errors occur, the type and code values indicate this error condition, and the variable called error may contain a pointer to another completion structure. QUESTION: What is "variable called error"? Such variable does not exist in Completion structure. It does not even contain a variable that holds a pointer to another completion structure. previousError fields in Completion structure only contains the array of ACSErr::ErrorTrace.
\\
Maybe this sentence could be simply removed?The particular values of the type and code are specific to the server implementation.
The completion structure may have a pointer to yet another completion, and so on. We see that all those completion structures form a linked list in the recursive error sequence, which called error stack.QUESTION: Again, Completion structure does not have a pointer to another completion. There is actually a linked list of ACSErr:ErrorTrace in previousError variable, but ACSErr::ErrorTrace does not contain a pointer to Completion structure according to the reference document 2. Does this sentence mean the device server can extend Completion structure as they want? If so, is it necessary to address this issue here? Hence it is possible to return and analyze the full stack of errors in the method call sequence, as specified in \[3\]. This is usually done by the ACS libraries, either in the BACI server or in the Abeans \[5\] client libraries. The application programmer is relieved from this work. We will therefore not go into details here. If the Completion type and code indicate an error-free condition, the error stack must be empty. 
Errors and alarms are returned through the completion structure and not via CORBA exceptions, because most of the method calls are asynchronous. Callbacks, which are executed on the client in a separate thread, cannot raise exceptions. For reasons of uniformity, also synchronously executed methods that deal with control processes, return the same completion structure.
If methods on remote objects (either Component or property) fail for unexpected reasons, in particular methods that do not even return a completion, such as calls to characteristics or invocation of monitors, then, and only then, exceptions are thrown. If the remote object can not be reached, then the local ORB raises a CORBA::NO_IMPLEMENT exception. If the remote object can not finish the request for whatever reason, it raises CORBA::NO_RESOURCES. These exceptions are unchecked, i.e. they are not predeclared in the signature of the method in the IDL file.

...