Chapter 11 - Create a Read Response For Your Driver

In a previous chapter from today's lesson, you created a read request. We asked you to return an instance of BYourDriverReadResponse from your read request's processReceive method (function). In this chapter you will learn how to code your read response class.

While following the examples in this chapter, please replace the text jarFileName, yourDriver and yourCompany as previously described in the Preparation section):

  1. Review your equipment's protocol documentation (again), especially where it describes the structure of the field-bus message that will be sent in reply to the read request that you constructed in a previous chapter of today's lesson.

    If you are working directly for the manufacturer of the equipment, then they should be able to provide you with one or more documents that describes the way in which the equipment communicates, plus the structure of the data that the equipment expects to see on the field-bus. If you have purchased this equipment then you will need to negotiate with the equipment's manufacturer in order to gain access to the equipment's protocol.

  2. Determine exactly which data values are returned in the response. If there are more than one then determine exactly how to extract the value for any particular data value in the response.
  3. Some protocols provide several messages that read point values. Some messages read point values as well as details about the point. For now, please only concern yourself with retrieving the actual value of the point, such as a single temperature value or other measurement. Please defer your concerns about retrieving extra information about the data point, such as engineering units (for example - whether it is Fahrenheit or Celsius) until later.
  4. Make a Java class that extends BDdfResponse and implements BIDdfReadResponse. Name it BYourDriverReadResponse. Create this in a package named com.yourCompany.yourDriver.comm.rsp. Also add an empty slotomatic comment immediately after the opening brace for the class declaration.

    To do this, create a text file named BYourDriverReadResponse.java in the jarFileName/src/com/yourCompany/yourDriver/comm/rsp folder. Inside the text file, start with the following text:

    package com.yourCompany.yourDriver.comm.rsp;
    
    import javax.baja.sys.*;
    import javax.baja.status.*;
    
    import com.tridium.ddf.comm.*;
    import com.tridium.ddf.comm.rsp.*;
    import com.tridium.ddf.comm.req.*;
    
    import com.yourCompany.yourDriver.identify.*;
    import com.yourCompany.yourDriver.point.*;
    
    public class BYourDriverReadResponse
      extends BDdfResponse
      implements BIDdfReadResponse
    {
      /*-
      class BYourDriverReadResponse
      {
      }
      -*/
    }
    

  5. Add a constructor that takes one parameter that is an IDdfDataFrame:

    A constructor is a special method (function) that is called when a particular instance of the class is allocated. To put this in perspective, the processReceive method that you coded in the previous chapter, will call the constructor on the read response class that you are creating in this chapter. Moreover, the processReceive method will pass in the IDdfDataFrame that it received from the dev driver framework. An IDdfDataFrame is essentially a byte array wrapper. In effect, your read request from the previous chapter will pass the bytes of the response into your read response's constructor.

    To add this constructor , add the following lines of text after the slotomatic comment of the class: >

      public BYourDriverReadResponse(IDdfDataFrame receiveFrame)
      {
      }
    

    You will need to make a copy of the bytes in the given data frame, since it could be a transient part of an internal buffer used in the dev communicator. Declare a byte array on the line that is immediately above the constructor. The byte array will hold a copy of the bytes that are passed to the constructor inside the IDdfDataFrame.

      private byte[] receiveBytes;
    

    Use the following code as the constructor that you already started making:

      private byte[] receiveBytes; // This is populated by the constructor
      private BYourDriverReadParams readParams; // This is populated by the constructor
      /**
       * This constructor is called by the processReceive method of
       * BYourDriverReadRequest.
       *
       * @param a reference to the data frame that matches up with
       * the request that was recently transmitted. The byte array
       * in this frame could be a direct reference to the dev
       * communicator's receiver's internal byte array so this
       * constructor copies the bytes into a safe instance array.
       * @param a reference to the read parameters structure that the
       * read request used to construct its own byte array.
       */
      public BYourDriverReadResponse(IDdfDataFrame receiveFrame, BYourDriverReadParams readParams)
      { // We will use the read parameters reference more for point discovery
        // (to be discussed much later in the tutorial)
        this.readParams = (BYourDriverReadParams)readParams.newCopy();
        // This copies the bytes of the internal receive buffer
        // Into a copy that is accessible to any other non-static
        // Functions on this class.
        byte[] receiveBuffer = receiveFrame.getFrameBytes();
        int receiveLength = receiveFrame.getFrameSize();
        // Allocates our own byte array to hold the copy
        receiveBytes=new byte[receiveLength];
        // Copies each byte from the receiveBuffer into our own
        // Safe array named receiveBytes.
        for (int i=0; i<receiveLength;i++)
          receiveBytes[i]=receiveBuffer[i];
      }
    

  6. Also add an empty constructor. An empty constructor might be required with future implementations of the developer driver framework in order to possibly allow client-side proxy copies of the request (if you do not understand what "client-side proxy" means -- you are not expected to know this -- then do not despair, please just keep this in the back of your mind and simply add the empty constructor.)

      /**
       * This empty constructor allows Niagara AX to instantiate
       * a client-side proxy of this request. It is not presently
       * used but could be required in future versions of the
       * developer driver framework.
       */
      public BYourDriverReadResponse()
      {
      }
    

  7. Please add a public method (function) named parseReadValue that takes one parameter, an IDdfReadable, and returns a BStatusValue. For now, please make this method return null. We will revisit this in a subsequent chapter of today's lesson. This method satisfies the BIDdfReadResponse interface.

      public BStatusValue parseReadValue(IDdfReadable readableSource)
      {
        return null;
      }
    

  8. Run slotomatic and perform a full build on your driver (as described in Chapter 2).