Skip to content

PIOT-CDA-08-003-A: Create a resource handler to process an actuation event from the GDA to the CDA #210

@labbenchstudios

Description

@labbenchstudios

Description

Create a new Python module with like-named class named AsyncUpdateActuatorResourceHandler.py.

  • This will allow the CDA to (eventually) be notified of an actuation event from the GDA consisting of an ActuatorData message. You can find templates for its non-Async definition in the programmingtheiot.cda.connection.handlers package.
  • NOTE: These instructions make use of the following CoAP library:
    • The aiocoap open source CoAP library, located at: aiocoap. Reference: Amsüss, Christian and Wasilak, Maciej. aiocoap: Python CoAP Library. Energy Harvesting Solutions, 2013–. http://github.com/chrysn/aiocoap/.

Review the README

  • Please see README.md for further information on, and use of, this content.
  • License for embedded documentation and source codes: PIOT-DOC-LIC

Estimated effort may vary greatly

  • The estimated level of effort for this exercise shown in the 'Estimate' section below is a very rough approximation. The actual level of effort may vary greatly depending on your development and test environment, experience with the requisite technologies, and many other factors.

Actions

Step 1: Create the module, class, and import statements for AsyncUpdateActuatorResourceHandler.py

  • Within the programmingtheiot.cda.connection.handlers package, create the new resource handler class as described above: AsyncUpdateActuatorResourceHandler
    • This class provides a simple implementation of a CoAP resource that will support updates from the GDA to the CDA when the GDA needs to send a command to the CDA. This will work with the ActuatorData data type.
    • Make sure the import statements for the class includes the appropriate module and class references for the library you're using.
  • Here are the import statements you'll need:
import logging

import aiocoap

from aiocoap.resource import Resource

from programmingtheiot.common.IDataMessageListener import IDataMessageListener

from programmingtheiot.data.DataUtil import DataUtil
from programmingtheiot.data.ActuatorData import ActuatorData
  • Here's a sample class implementation for AsyncUpdateActuatorResourceHandler
class AsyncUpdateActuatorResourceHandler():
	"""
	Standard resource that will handle an incoming actuation command,
	and return the command response.
	
	NOTE: Your implementation will likely need to extend from the selected
	CoAP library's resource base class.
	
	"""

	def __init__(self, dataMsgListener: IDataMessageListener = None):
		self.dataMsgListener = dataMsgListener
		self.dataUtil = DataUtil()
		
	async def render_put(self, request):
		try:
			responseCode = aiocoap.Code.NOT_ACCEPTABLE
			 
			# TODO: validate the request!
			# Check payload
			# Check content-type (should be JSON)
			actuatorCmdData = self.dataUtil.jsonToActuatorData(request.payload)
			
			logging.info('Handling PUT request: ' + actuatorCmdData)
			
			return self._createResponse(actuatorCmdData)
			
		except:
			logging.warning("Failed to validate and convert actuation command.")
			
		return aiocoap.Message(code = responseCode)
	
	def _createResponse(self, data: ActuatorData = None):
		responseCode = aiocoap.Code.CHANGED 
		
		actuatorResponseData = self.dataMsgListener.handleActuatorCommandMessage(data)
		
		# TODO: validate the data and convert to JSON
		
		# return a Message instance
		jsonData = self.dataUtil.actuatorDataToJson(actuatorResponseData)
		return aiocoap.Message(code = responseCode, payload = jsonData.encode('ascii'))
  • NOTE: The type IDataMessageListener should already exist within your CDA repository as part of the programmingtheiot.common package, and should not need any modifications.
    • While Python doesn't support interfaces, this provides a base class with method definitions that should make it easier to invoke the DeviceDataManager callback handleActuatorCommandMessage(ActuatorData)

Estimate (Small = < 2 hrs; Medium = 4 hrs; Large = 8 hrs)

  • Medium

Tests

  • You can use the Californium client described in PIOT-CFG-08-001 to test your CoAP server running within the CDA.

Configure the CDA to run with CoAP server enabled

  • Make sure your CDA's configuration file is updated to enable the CoAP server
    • Update the config file and start the CDA in a separate terminal (or within your IDE)
    • NOTE: The config info below is JUST AN EXAMPLE
#
# CoAP client configuration information
#
[Coap.GatewayService]
credFile       = ./cred/PiotCoapCred.props
certFile       = ./cert/PiotCoapLocalCertFile.pem
host           = localhost
port           = 5683
securePort     = 5684
enableAuth     = False
enableCrypt    = False

#
# CDA specific configuration information
#
[ConstrainedDevice]
deviceLocationID = constraineddevice001
enableSimulator  = True
enableEmulator   = False
enableSenseHAT   = False
enableMqttClient = False
enableCoapServer = True
enableCoapClient = False
enableSystemPerformance = True
enableSensing    = True
enableLogging    = True
pollCycleSecs    = 5
testGdaDataPath  = /tmp/gda-data
testCdaDataPath  = /tmp/cda-data
testEmptyApp     = False
runForever       = True

Configure and run the Californium Client

  • Open a separate terminal window on your system to run the Californium client.
    • Change directory to the Californium Tools path (INSTALL_PATH/californium.tools)
    • Run cf-client with a simple discover or get request

CoAP GET Example

cd cf-client/target
java -jar cf-client-3.10.0-SNAPSHOT.jar -m GET coap://localhost:5683

CoAP DISCOVER Example

cd cf-client/target
java -jar cf-client-3.10.0-SNAPSHOT.jar -m GET coap://localhost:5683/.well-known/core

Californium client help

  • For a list of supported client parameters, use the following:
java -jar cf-client-3.10.0-SNAPSHOT.jar --help

Results (Initial)

  • You should see something similar to the following, depending on how the server is configured:
    • NOTE: The following is an example response from a DISCOVER request

Results (Upon Full Lab Module Completion)

  • Once you've completed all the exercises in this lab module, you should see an output that looks similar to the following, depending on how the server is configured:
    • NOTE: The following is an example response from a DISCOVER request when using the aiocoap library.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Lab Module 08 - CoAP Servers

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions