Adding CoAP to our actuator

Adding CoAP to the actuator is done in more or less the same way as the sensor. The main difference between the two is that the resources will be used for the control resource instead of data readout. For this reason, the POST method will be used instead of GET to send data to the actuator. We start by adding a CoAP endpoint to our actuator, as follows:

CoapEndpoint CoapEndpoint = new CoapEndpoint ();
Log.Information ("CoAP endpoint receiving requests on port " + CoapEndpoint.Port.ToString ());

Defining simple control resources

First, we define a series of simple control resources named do N /txt that can be used to read the state of the digital output, as well as change their status using simple plain text GET and POST method calls. In the resource name, N is used to identify which digital output is being referred to. When we register the resource, we need to provide two delegates. The first delegate will handle the GET method call and the second delegate will handle the POST method call. This can be seen in the following code snippet:

for(i = 1; i <= 8; i++)
{
  CoapEndpoint.RegisterResource("do" + i.ToString() + "/txt", "Digital Output " + i.ToString() + ", as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, false, CoapGetDigitalOutputTxt, CoapSetDigitalOutputTxt);
}

Similarly, we define a compound resource named do/txt that can be used to manage all the output in one operation:

CoapEndpoint.RegisterResource("do/txt", "Digital Outputs, as a number 0-255 as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, false, CoapGetDigitalOutputsTxt, CoapSetDigitalOutputsTxt);

We also publish a simple resource named alarm/txt for the alarm:

CoapEndpoint.RegisterResource("alarm/txt", "Alarm Output " + i.ToString () + ", as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, false, CoapGetAlarmOutputTxt, CoapSetAlarmOutputTxt);

Tip

The source code for the actuator project also contains resources to provide the sensor data readout of the actuator. This is implemented in the same manner as for the sensor project.

Parsing the URL in CoAP

The CoapGetDigitlOutputTxt method uses the URL to identify which digital output is being referenced. In CoAP, you don't need to parse the URL as a string since the request is not made in the form of a string URL to begin with. Instead, all parts of the URL are sent as options in the request. To start, let's first define our GET method that returns the current state of a digital output:

private static object CoapGetDigitalOutputTxt (CoapRequest Request, object DecodedPayload)
{
  int Index;

  if(!GetDigitalOutputIndex(Request, out Index))
    throw new CoapException (CoapResponseCode.ClientError_NotFound);
    return digitalOutputs [Index - 1].Value ? "1" : "0";
}

So, to find the digital output, we need to loop through the options of the CoAP request, single out the URI Path options (defined by the CoapOptionUriPath class, which is defined in the Clayster.Library.Internet.CoAP.Options namespace), and then extract the index from these options if found. Note that each segment in the path is represented by a UriPath option. So, the do1/txt resource is represented by two URI path options: one for do1 and another for txt. This can be done as follows:

private static bool GetDigitalOutputIndex (CoapRequest Request,
  out int Index)
{
  CoapOptionUriPath Path;
  Index = 0;
  foreach (CoapOption Option in Request.Options)
  {
    if ((Path = Option as CoapOptionUriPath) != null &&
      Path.Value.StartsWith ("do"))
    {
      if (int.TryParse (Path.Value.Substring (2), 
        out Index))
        return true;
    }
  }

  return false;
}

Tip

Other useful options include the CoapOptionAccept option, where the client tells the server what type of content it desires, and the CoapOptionUriQuery option, where each similar option provides one query statement of the form p=v for a parameter p and a value v.

Controlling the output using CoAP

The CoapGetDigitlOutputTxt method defined in the previous section returns a simple string containing 1 if the corresponding digital output is high and 0 if it is low. Let's now implement the POST method that will allow us to control the output using the text payload provided in the same format. We first define the method as follows:

private static object CoapSetDigitalOutputTxt (CoapRequest Request, object DecodedPayload)
{
  int Index;
  if(!GetDigitalOutputIndex (Request, out Index))
    throw new CoapException (CoapResponseCode.ClientError_NotFound);

Data posted along with the method call is found in the DecodedPayload parameter. What type of value this is depends on how the call was encoded. We first check whether it has been encoded as a plain text string:

string s = DecodedPayload as string;

If Content-Format information is left out of the call, the decoder wouldn't know how to decode the payload. In this case, the payload is simply an array of bytes. To improve interoperability, we will provide default decoding of such data by explicitly converting it into a string, as follows:

if(s == null && DecodedPayload is byte[])
  s = System.Text.Encoding.UTF8.GetString ((byte[])DecodedPayload);

Next, we have to parse the string. If not successful, we consider it a bad request and return a corresponding error to the caller:

bool b;
if(s == null || !XmlUtilities.TryParseBoolean (s, out b))
  throw new CoapException (CoapResponseCode.ClientError_BadRequest);

We then perform the actual control in the same manner as done in the case of HTTP. When done, we return a successful response code to the caller in the following manner:

  return CoapResponseCode.Success_Changed;
}

Tip

Notice that when returning content, you return the object itself. A CoAP encoder will be assigned that will encode the object for you. In this case, the response code of the message will automatically be set to Success_Content. If you don't want to return any content and only return a specific response code, you simply need to return a value of the CoapResponseCode enumeration type.

The other control methods are implemented in a similar manner and can be viewed in the source code for the Actuator project.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.109.34