def __init__(self): self.config = ConfigUtil() self.dataMsgListener = None self.coapClient = None self.host = self.config.getProperty(ConfigConst.COAP_GATEWAY_SERVICE, ConfigConst.HOST_KEY, ConfigConst.DEFAULT_HOST) self.port = self.config.getInteger(ConfigConst.COAP_GATEWAY_SERVICE, ConfigConst.PORT_KEY, ConfigConst.DEFAULT_COAP_PORT) logging.info('\tCoAP Server Host: ' + self.host) logging.info('\tCoAP Server Port: ' + str(self.port)) self.url = "coap://" + self.host + ":" + str(self.port) + "/" try: logging.info("Parsing URL: " + self.url) self.host, self.port, self.path = parse_uri(self.url) tmpHost = socket.gethostbyname(self.host) if tmpHost: self.host = tmpHost self._initClient() else: logging.error("Can't resolve host: " + self.host) except socket.gaierror: logging.info("Failed to resolve host: " + self.host)
def __init__(self, enableMqtt: bool = True, enableCoap: bool = False): self.dataUtil = DataUtil() self.enableMqttClient = enableMqtt self.sysPerfManager = SystemPerformanceManager() self.sysPerfManager.setDataMessageListener(self) self.sensorAdapterManager = SensorAdapterManager() self.sensorAdapterManager.setDataMessageListener(self) self.actuatorAdapterManager = ActuatorAdapterManager() self.actuatorAdapterManager.setDataMessageListener(self) self.configUtil = ConfigUtil() self.enableHandleTempChangeOnDevice = self.configUtil.getBoolean( ConfigConst.CONSTRAINED_DEVICE, ConfigConst.ENABLE_HANDLE_TEMP_CHANGE_ON_DEVICE_KEY) self.triggerHvacTempFloor = self.configUtil.getFloat( ConfigConst.CONSTRAINED_DEVICE, ConfigConst.TRIGGER_HVAC_TEMP_FLOOR_KEY) self.triggerHvacTempCeiling = self.configUtil.getFloat( ConfigConst.CONSTRAINED_DEVICE, ConfigConst.TRIGGER_HVAC_TEMP_CEILING_KEY) self.triggerHvacTempFloor = 10.0 self.triggerHvacTempCeiling = 30.0 if self.enableMqttClient: self.mqttClient = MqttClientConnector() self.mqttClient.setDataMessageListener(self)
def setUpClass(self): logging.basicConfig( format='%(asctime)s:%(module)s:%(levelname)s:%(message)s', level=logging.DEBUG) logging.info("Testing MqttClientConnector class...") self.cfg = ConfigUtil() self.mcc = MqttClientConnector( clientID='CDAMqttClientConnectorTest001')
def __init__(self): super(HeartRateDownEmulatorTask, self).__init__(actuatorType=ActuatorData.HEART_RATE_ACTUATOR_TYPE_DOWN, simpleName="HEART_RATE_ACTUATOR_TYPE_DOWN", actuatorName = ConfigConst.HEART_RATE_DOWN_ACTUATOR_NAME) self.sh = SenseHAT(emulate=True) configUtil = ConfigUtil() flag = configUtil.getBoolean(ConfigConst.CONSTRAINED_DEVICE, ConfigConst.ENABLE_SENSE_HAT_KEY) if flag: self.sh = SenseHAT(emulate=True) else: self.sh = SenseHAT(emulate=False)
def __init__(self): super(LedDisplayEmulatorTask, self).__init__(actuatorType=ActuatorData.LED_DISPLAY_ACTUATOR_TYPE, simpleName="LED_Display", actuatorName = ConfigConst.LED_ACTUATOR_NAME) self.sh = SenseHAT(emulate=True) configUtil = ConfigUtil() flag = configUtil.getBoolean(ConfigConst.CONSTRAINED_DEVICE, ConfigConst.ENABLE_SENSE_HAT_KEY) if flag: self.sh = SenseHAT(emulate=True) else: self.sh = SenseHAT(emulate=False)
def __init__(self, dataSet=None): super(BodyTemperatureSensorEmulatorTask, self).__init__(SensorData.BODY_TEMP_SENSOR_TYPE, minVal=SensorDataGenerator.LOW_NORMAL_INDOOR_TEMP, maxVal=SensorDataGenerator.HI_NORMAL_INDOOR_TEMP, sensorName= ConfigConst.BODY_TEMP_SENSOR_NAME) self.sh = SenseHAT(emulate=True) configUtil = ConfigUtil() flag = configUtil.getBoolean(ConfigConst.CONSTRAINED_DEVICE, ConfigConst.ENABLE_SENSE_HAT_KEY) if flag: self.sh = SenseHAT(emulate=True) else: self.sh = SenseHAT(emulate=False)
def __init__(self): super(BodyTemperatureUpEmulatorTask, self).__init__( actuatorType=ActuatorData.BODY_TEMP_ACTUATOR_TYPE_UP, simpleName="BODY_TEMP_ACTUATOR_TYPE_UP", actuatorName=ConfigConst.BODY_TEMP_UP_ACTUATOR_NAME) self.sh = SenseHAT(emulate=True) configUtil = ConfigUtil() flag = configUtil.getBoolean(ConfigConst.CONSTRAINED_DEVICE, ConfigConst.ENABLE_SENSE_HAT_KEY) if flag: self.sh = SenseHAT(emulate=True) else: self.sh = SenseHAT(emulate=False)
def __init__(self, dataSet=None): super(HeartRateSensorEmulatorTask, self).__init__(SensorData.HEART_RATE_SENSOR_TYPE, minVal=SensorDataGenerator.LOW_NORMAL_ENV_HUMIDITY, maxVal=SensorDataGenerator.HI_NORMAL_ENV_HUMIDITY, sensorName=ConfigConst.HEART_RATE_SENSOR_NAME) # Create an instance of SenseHAT and set the emulate flag to True if running the emulator, or False if using real hardware # This can be read from ConfigUtil using the ConfigConst.CONSTRAINED_DEVICE section and the ConfigConst.ENABLE_SENSE_HAT_KEY # If the ConfigConst.ENABLE_SENSE_HAT_KEY is False, set the emulate flag to True, otherwise set to False self.sh = SenseHAT(emulate=True) configUtil = ConfigUtil() flag = configUtil.getBoolean(ConfigConst.CONSTRAINED_DEVICE, ConfigConst.ENABLE_SENSE_HAT_KEY) if flag: self.sh = SenseHAT(emulate=True) else: self.sh = SenseHAT(emulate=False)
def __init__(self): super(BloodPressureUpEmulatorTask, self).__init__( actuatorType=ActuatorData.BLOOD_PRESSURE_ACTUATOR_TYPE_UP, simpleName="BLOOD_PRESSURE_ACTUATOR_TYPE_UP", actuatorName=ConfigConst.BLOOD_PRESSURE_UP_ACTUATOR_NAME) # Create an instance of SenseHAT and set the emulate flag to True if running the emulator, or False if using real hardware # This can be read from ConfigUtil using the ConfigConst.CONSTRAINED_DEVICE section and the ConfigConst.ENABLE_SENSE_HAT_KEY # If the ConfigConst.ENABLE_SENSE_HAT_KEY is False, set the emulate flag to True, otherwise set to False self.sh = SenseHAT(emulate=True) configUtil = ConfigUtil() flag = configUtil.getBoolean(ConfigConst.CONSTRAINED_DEVICE, ConfigConst.ENABLE_SENSE_HAT_KEY) if flag: self.sh = SenseHAT(emulate=True) else: self.sh = SenseHAT(emulate=False)
def setUpClass(self): logging.basicConfig( format='%(asctime)s:%(module)s:%(levelname)s:%(message)s', level=logging.DEBUG) logging.info("Running DataIntegrationTest test cases...") encodeToUtf8 = False self.dataUtil = DataUtil(encodeToUtf8) self.cdaDataPath = ConfigUtil().getProperty( ConfigConst.CONSTRAINED_DEVICE, ConfigConst.TEST_CDA_DATA_PATH_KEY) self.gdaDataPath = ConfigUtil().getProperty( ConfigConst.CONSTRAINED_DEVICE, ConfigConst.TEST_GDA_DATA_PATH_KEY) if not os.path.exists(self.cdaDataPath): logging.info("================================================") logging.info("DataIntegrationTest - path needs to be created: " + self.cdaDataPath) os.makedirs(self.cdaDataPath, exist_ok=True)
class CoapClientConnector(IRequestResponseClient): """ Shell representation of class for student implementation. """ def __init__(self): self.config = ConfigUtil() self.dataMsgListener = None self.coapClient = None self.host = self.config.getProperty(ConfigConst.COAP_GATEWAY_SERVICE, ConfigConst.HOST_KEY, ConfigConst.DEFAULT_HOST) self.port = self.config.getInteger(ConfigConst.COAP_GATEWAY_SERVICE, ConfigConst.PORT_KEY, ConfigConst.DEFAULT_COAP_PORT) logging.info('\tCoAP Server Host: ' + self.host) logging.info('\tCoAP Server Port: ' + str(self.port)) self.url = "coap://" + self.host + ":" + str(self.port) + "/" try: logging.info("Parsing URL: " + self.url) self.host, self.port, self.path = parse_uri(self.url) tmpHost = socket.gethostbyname(self.host) if tmpHost: self.host = tmpHost self._initClient() else: logging.error("Can't resolve host: " + self.host) except socket.gaierror: logging.info("Failed to resolve host: " + self.host) def sendDiscoveryRequest( self, timeout: int = IRequestResponseClient.DEFAULT_TIMEOUT) -> bool: logging.info('Discovering remote resources...') # NOTE: we can use the API to send a discovery 'GET', or - per [RFC7252](https://tools.ietf.org/html/rfc7252#section-7.2) # and its reference of [RFC6690](https://tools.ietf.org/html/rfc6690#section-1.2.1), we can just send the following: self.coapClient.get(path='/.well-known/core', callback=self._onDiscoveryResponse, timeout=timeout) return True def sendDeleteRequest( self, resource: ResourceNameEnum, enableCON=False, timeout: int = IRequestResponseClient.DEFAULT_TIMEOUT) -> bool: if resource: logging.debug("Issuing DELETE with path: " + resource.value) request = self.coapClient.mk_request(defines.Codes.DELETE, path=resource.value) request.token = generate_random_token(2) if not enableCON: request.type = defines.Types["NON"] self.coapClient.send_request(request=request, callback=self._onDeleteResponse, timeout=timeout) else: logging.warning( "Can't test DELETE - no path or path list provided.") def _onDeleteResponse(self, response): logging.info('DELETE response received.') if response: logging.info('Token: ' + str(response.token)) logging.info(str(response.location_path)) logging.info(str(response.payload)) def sendGetRequest( self, resource: ResourceNameEnum, enableCON=False, timeout: int = IRequestResponseClient.DEFAULT_TIMEOUT) -> bool: logging.info("sendGetRequest is Called") if resource: logging.debug("Issuing GET with path: " + resource.value) request = self.coapClient.mk_request(defines.Codes.GET, path=resource.value) request.token = generate_random_token(2) if not enableCON: request.type = defines.Types["NON"] self.coapClient.send_request(request=request, callback=self._onGetResponse, timeout=timeout) else: logging.warning("Can't test GET - no path or path list provided.") return False def _onGetResponse(self, response): logging.info('GET response received.') if response: logging.info('Token: ' + str(response.token)) logging.info(str(response.location_path)) logging.info(str(response.payload)) # # NOTE: This next section is optional if you want to send a callback to the self.dataMsgListener instance # # TODO: get the URI and convert to ResourceNameEnum resource = None if self.dataMsgListener: self.dataMsgListener.handleIncomingMessage( resource, str(response.payload)) def sendPostRequest( self, resource: ResourceNameEnum, payload=None, enableCON=False, timeout: int = IRequestResponseClient.DEFAULT_TIMEOUT) -> bool: if resource: """logging.debug("Issuing POST with path: " + resource.value)""" request = self.coapClient.mk_request(defines.Codes.POST, path=resource.value) request.token = generate_random_token(2) request.payload = payload if not enableCON: request.type = defines.Types["NON"] self.coapClient.send_request(request=request, callback=self._onPostResponse, timeout=timeout) else: """logging.warning("Can't test POST - no path or path list provided.")""" def _onPostResponse(self, response): """logging.info('POST response received.')""" if response: logging.info('Token: ' + str(response.token)) logging.info(str(response.location_path)) logging.info(str(response.payload)) def sendPutRequest( self, resource: ResourceNameEnum, payload=None, enableCON=False, timeout: int = IRequestResponseClient.DEFAULT_TIMEOUT) -> bool: if resource: """logging.debug("Issuing PUT with path: " + resource.value)""" request = self.coapClient.mk_request(defines.Codes.PUT, path=resource.value) request.token = generate_random_token(2) request.payload = payload if not enableCON: request.type = defines.Types["NON"] self.coapClient.send_request(request=request, callback=self._onPutResponse, timeout=timeout) else: """logging.warning("Can't test PUT - no path or path list provided.")""" def _onPutResponse(self, response): """logging.info('PUT response received.')""" if response: logging.info('Token: ' + str(response.token)) logging.info(str(response.location_path)) logging.info(str(response.payload)) def setDataMessageListener(self, listener: IDataMessageListener) -> bool: self.dataMsgListener = listener return True def startObserver(self, resource: ResourceNameEnum, ttl: int = IRequestResponseClient.DEFAULT_TTL) -> bool: pass def stopObserver( self, timeout: int = IRequestResponseClient.DEFAULT_TIMEOUT) -> bool: pass def _initClient(self): if not self.coapClient: self.coapClient = HelperClient(server=(self.host, self.port)) def _onDiscoveryResponse(self, response): if response: logging.info(response.pretty_print()) # get the payload and convert to a list of paths if response.payload is None: logging.info(' Path entry [' ']:' + 'None') return self.pathList = response.payload.split(',') index = 0 # the following is optional, but provides an easy way to track all the returned resource names for path in self.pathList: for char in '<\>': path = path.replace(char, '') self.pathList[index] = path logging.info(' Path entry [' + str(index) + ']:' + self.pathList[index]) index += 1 else: logging.info("No response received.")
class ConfigUtilTest(unittest.TestCase): """ This test case class contains very basic unit tests for ConfigUtil. It should not be considered complete, but serve as a starting point for the student implementing additional functionality within their Programming the IoT environment. """ DEFAULT_USER = "******" DEFAULT_AUTH = "Bar" # optionally test the following files # - EmptyTestConfig.props # - InvalidTestConfig.props # - None (which will default to ./config/PiotConfig.props) configFile = "./ValidTestConfig.props" @classmethod def setUpClass(self): logging.basicConfig( format='%(asctime)s:%(module)s:%(levelname)s:%(message)s', level=logging.DEBUG) logging.info("Testing ConfigUtil class...") self.configUtil = ConfigUtil(configFile=self.configFile) def setUp(self): pass def tearDown(self): pass def testGetBooleanProperty(self): enableLogging = self.configUtil.hasProperty( ConfigConst.CONSTRAINED_DEVICE, ConfigConst.ENABLE_LOGGING_KEY) self.assertTrue(enableLogging) def testGetCredentials(self): creds = self.configUtil.getCredentials(ConfigConst.CONSTRAINED_DEVICE) self.assertIsNotNone(creds) self.assertEqual(creds[ConfigConst.USER_NAME_TOKEN_KEY], self.DEFAULT_USER) self.assertEqual(creds[ConfigConst.USER_AUTH_TOKEN_KEY], self.DEFAULT_AUTH) pass def testGetIntegerProperty(self): port = self.configUtil.getInteger(ConfigConst.MQTT_GATEWAY_SERVICE, ConfigConst.PORT_KEY) self.assertEqual(port, ConfigConst.DEFAULT_MQTT_PORT) def testGetFloatProperty(self): hSimFloor = self.configUtil.getFloat( ConfigConst.CONSTRAINED_DEVICE, ConfigConst.HUMIDITY_SIM_FLOOR_KEY) self.assertGreater(hSimFloor, 0.0) def testGetProperty(self): hostName = self.configUtil.getProperty( ConfigConst.MQTT_GATEWAY_SERVICE, ConfigConst.HOST_KEY) self.assertTrue(hostName) def testHasProperty(self): self.assertTrue( self.configUtil.hasProperty(ConfigConst.CONSTRAINED_DEVICE, ConfigConst.ENABLE_EMULATOR_KEY)) def testHasSection(self): self.assertTrue( self.configUtil.hasSection(ConfigConst.CONSTRAINED_DEVICE)) def testIsConfigDataLoaded(self): self.assertTrue(self.configUtil.isConfigDataLoaded())
class DeviceDataManager(IDataMessageListener): """ Shell representation of class for student implementation. """ def __init__(self, enableMqtt: bool = True, enableCoap: bool = False): self.dataUtil = DataUtil() self.enableMqttClient = enableMqtt self.sysPerfManager = SystemPerformanceManager() self.sysPerfManager.setDataMessageListener(self) self.sensorAdapterManager = SensorAdapterManager() self.sensorAdapterManager.setDataMessageListener(self) self.actuatorAdapterManager = ActuatorAdapterManager() self.actuatorAdapterManager.setDataMessageListener(self) self.configUtil = ConfigUtil() self.enableHandleTempChangeOnDevice = self.configUtil.getBoolean( ConfigConst.CONSTRAINED_DEVICE, ConfigConst.ENABLE_HANDLE_TEMP_CHANGE_ON_DEVICE_KEY) self.triggerHvacTempFloor = self.configUtil.getFloat( ConfigConst.CONSTRAINED_DEVICE, ConfigConst.TRIGGER_HVAC_TEMP_FLOOR_KEY) self.triggerHvacTempCeiling = self.configUtil.getFloat( ConfigConst.CONSTRAINED_DEVICE, ConfigConst.TRIGGER_HVAC_TEMP_CEILING_KEY) self.triggerHvacTempFloor = 10.0 self.triggerHvacTempCeiling = 30.0 if self.enableMqttClient: self.mqttClient = MqttClientConnector() self.mqttClient.setDataMessageListener(self) def handleActuatorCommandResponse(self, data: ActuatorData) -> bool: d = self.dataUtil.actuatorDataToJson(data) logging.info("Incoming actuator response received" + d) #self.mqttClient.publishMessage(ResourceNameEnum.CDA_ACTUATOR_RESPONSE_RESOURCE, d, 1) self._handleUpstreamTransmission( ResourceNameEnum.CDA_ACTUATOR_RESPONSE_RESOURCE, d) def handleIncomingMessage(self, resourceEnum: ResourceNameEnum, msg: str) -> bool: logging.info("called handleIncomingMessage function") actuatorData = self.dataUtil.jsonToActuatorData(msg) if not actuatorData: logging.warning("not legal JSON data") else: self._handleIncomingDataAnalysis(msg) def handleSensorMessage(self, data: SensorData) -> bool: logging.info("CDA Handling sensor message...") d = self.dataUtil.sensorDataToJson(data) #self._handleUpstreamTransmission(ResourceNameEnum.CDA_SENSOR_MSG_RESOURCE, d) ''' just for test : CDA analysis temperature data ''' if data.sensorType is SensorData.HEART_RATE_SENSOR_TYPE: self._handleSensorDataAnalysis(data) if self.enableMqttClient: self.mqttClient.publishMessage( ResourceNameEnum.CDA_SENSOR_MSG_RESOURCE, d, 0) return True def handleSystemPerformanceMessage(self, data: SystemPerformanceData) -> bool: logging.info("Handle system performance message...") d = self.dataUtil.systemPerformanceDataToJson(data) if self.enableMqttClient: self.mqttClient.publishMessage( ResourceNameEnum.CDA_SYSTEM_PERF_MSG_RESOURCE, d) def startManager(self): logging.info('DeviceDataManager was started') self.sysPerfManager.startManager() self.sensorAdapterManager.startManager() if self.enableMqttClient: self.mqttClient.connectClient() def stopManager(self): logging.info('DeviceDataManager was stopped') self.sysPerfManager.stopManager() self.sensorAdapterManager.stopManager() if self.enableMqttClient: self.mqttClient.disconnectClient() def _handleIncomingDataAnalysis(self, msg: str): """ Call this from handleIncomeMessage() to determine if there's any action to take on the message. Steps to take: 1) Validate msg: Most will be ActuatorData, but you may pass other info as well. 2) Convert msg: Use DataUtil to convert if appropriate. 3) Act on msg: Determine what - if any - action is required, and execute. """ logging.info('called _handleIncomingDataAnalysis function') actuatorData = self.dataUtil.jsonToActuatorData(msg) if not actuatorData: logging.warning("not legal JSON data") else: self.actuatorAdapterManager.sendActuatorCommand(actuatorData) def _handleSensorDataAnalysis(self, data: SensorData): """ Call this from handleSensorMessage() to determine if there's any action to take on the message. Steps to take: 1) Check config: Is there a rule or flag that requires immediate processing of data? 2) Act on data: If # 1 is true, determine what - if any - action is required, and execute. """ logging.info("_handleSensorDataAnalysis is called." + str(data)) #actuatorData = ActuatorData(ActuatorData.PATIENT_ACTUATOR_TYPE) if data.getValue() > 90: actuatorData = ActuatorData( ActuatorData.HEART_RATE_ACTUATOR_TYPE_UP) actuatorData.setCommand(ActuatorData.COMMAND_ON) self.actuatorAdapterManager.sendActuatorCommand(actuatorData) def _handleUpstreamTransmission(self, resourceName: ResourceNameEnum, msg: str): """ Call this from handleActuatorCommandResponse(), handlesensorMessage(), and handleSystemPerformanceMessage() to determine if the message should be sent upstream. Steps to take: 1) Check connection: Is there a client connection configured (and valid) to a remote MQTT or CoAP server? 2) Act on msg: If # 1 is true, send message upstream using one (or both) client connections. """ logging.info("_handleUpstreamTransmission is called.") if self.enableMqttClient: logging.info("mqtt handle publish") self.mqttClient.publishMessage(resourceName, msg, 0) def handleActuatorCommandMessage(self, data: ActuatorData) -> bool: if data: logging.info("Processing actuator command message.") # TODO: add further validation before sending the command self.actuatorAdapterManager.sendActuatorCommand(data) return True else: logging.warning( "Received invalid ActuatorData command message. Ignoring.") return False
def setUp(self): self.mqttClient = MqttClientConnector( clientID='CDAMqttClientPerformanceTest001') self.cfg = ConfigUtil() pass
class MqttClientPerformanceTest(unittest.TestCase): NS_IN_MILLIS = 1000000 # NOTE: We'll use only 10,000 requests for MQTT MAX_TEST_RUNS = 10000 @classmethod def setUpClass(self): logging.basicConfig( format='%(asctime)s:%(module)s:%(levelname)s:%(message)s', level=logging.DEBUG) def setUp(self): self.mqttClient = MqttClientConnector( clientID='CDAMqttClientPerformanceTest001') self.cfg = ConfigUtil() pass def tearDown(self): pass # @unittest.skip("Ignore for now.") def testConnectAndDisconnect(self): startTime = time.time_ns() delay = self.cfg.getInteger(ConfigConst.MQTT_GATEWAY_SERVICE, ConfigConst.KEEP_ALIVE_KEY, ConfigConst.DEFAULT_KEEP_ALIVE) self.assertTrue(self.mqttClient.connectClient()) sleep(delay + 5) self.assertTrue(self.mqttClient.disconnectClient()) endTime = time.time_ns() elapsedMillis = (endTime - startTime) / self.NS_IN_MILLIS logging.info("Connect and Disconnect: " + str(elapsedMillis) + " ms") # @unittest.skip("Ignore for now.") def testPublishQoS0(self): self._execTestPublish(self.MAX_TEST_RUNS, 0) # @unittest.skip("Ignore for now.") def testPublishQoS1(self): self._execTestPublish(self.MAX_TEST_RUNS, 1) # @unittest.skip("Ignore for now.") def testPublishQoS2(self): self._execTestPublish(self.MAX_TEST_RUNS, 2) def _execTestPublish(self, maxTestRuns: int, qos: int): self.assertTrue(self.mqttClient.connectClient()) sensorData = SensorData() payload = DataUtil().sensorDataToJson(sensorData) startTime = time.time_ns() for seqNo in range(0, maxTestRuns): self.mqttClient.publishMessage( resource=ResourceNameEnum.CDA_SENSOR_MSG_RESOURCE, msg=payload, qos=qos) endTime = time.time_ns() elapsedMillis = (endTime - startTime) / self.NS_IN_MILLIS self.assertTrue(self.mqttClient.disconnectClient()) logging.info("Publish message - QoS " + str(qos) + " [" + str(maxTestRuns) + "]: " + str(elapsedMillis) + " ms")
def setUpClass(self): logging.basicConfig( format='%(asctime)s:%(module)s:%(levelname)s:%(message)s', level=logging.DEBUG) logging.info("Testing ConfigUtil class...") self.configUtil = ConfigUtil(configFile=self.configFile)
class MqttClientConnectorTest(unittest.TestCase): """ This test case class contains very basic unit tests for MqttClientConnector. It should not be considered complete, but serve as a starting point for the student implementing additional functionality within their Programming the IoT environment. """ @classmethod def setUpClass(self): logging.basicConfig( format='%(asctime)s:%(module)s:%(levelname)s:%(message)s', level=logging.DEBUG) logging.info("Testing MqttClientConnector class...") self.cfg = ConfigUtil() self.mcc = MqttClientConnector( clientID='CDAMqttClientConnectorTest001') def setUp(self): pass def tearDown(self): pass # @unittest.skip("Ignore for now.") def testConnectAndDisconnect(self): delay = self.cfg.getInteger(ConfigConst.MQTT_GATEWAY_SERVICE, ConfigConst.KEEP_ALIVE_KEY, ConfigConst.DEFAULT_KEEP_ALIVE) self.mcc.connectClient() sleep(delay + 5) self.mcc.disconnectClient() # @unittest.skip("Ignore for now.") def testConnectAndPublish(self): qos = 1 delay = self.cfg.getInteger(ConfigConst.MQTT_GATEWAY_SERVICE, ConfigConst.KEEP_ALIVE_KEY, ConfigConst.DEFAULT_KEEP_ALIVE) listener = DefaultDataMessageListener() self.mcc.connectClient() self.mcc.subscribeToTopic( ResourceNameEnum.CDA_MGMT_STATUS_MSG_RESOURCE, qos) sleep(5) self.mcc.publishMessage(ResourceNameEnum.CDA_MGMT_STATUS_MSG_RESOURCE, "TEST: This is the CDA message payload.", qos) sleep(5) self.mcc.unsubscribeFromTopic( ResourceNameEnum.CDA_MGMT_STATUS_MSG_RESOURCE) sleep(5) sleep(delay) self.mcc.disconnectClient() # @unittest.skip("Ignore for now.") def testIntegrateWithGdaSubscribeCdaCmdTopic(self): qos = 1 delay = self.cfg.getInteger(ConfigConst.MQTT_GATEWAY_SERVICE, ConfigConst.KEEP_ALIVE_KEY, ConfigConst.DEFAULT_KEEP_ALIVE) listener = DefaultDataMessageListener() self.mcc.connectClient() self.mcc.subscribeToTopic( ResourceNameEnum.CDA_MGMT_STATUS_CMD_RESOURCE, qos) sleep(delay) self.mcc.disconnectClient() # @unittest.skip("Ignore for now.") def testIntegrateWithGdaPublishCdaMgmtTopic(self): qos = 1 delay = self.cfg.getInteger(ConfigConst.MQTT_GATEWAY_SERVICE, ConfigConst.KEEP_ALIVE_KEY, ConfigConst.DEFAULT_KEEP_ALIVE) listener = DefaultDataMessageListener() self.mcc.connectClient() self.mcc.publishMessage(ResourceNameEnum.CDA_MGMT_STATUS_MSG_RESOURCE, "TEST: This is the CDA message payload.", qos) sleep(5) self.mcc.disconnectClient() def testActuatorCmdPubSub(self): qos = 1 # NOTE: delay can be anything you'd like - the sleep() calls are simply to slow things down a bit for observation delay = self.cfg.getInteger(ConfigConst.MQTT_GATEWAY_SERVICE, ConfigConst.KEEP_ALIVE_KEY, ConfigConst.DEFAULT_KEEP_ALIVE) actuatorData = ActuatorData() payload = DataUtil().actuatorDataToJson(actuatorData) self.mcc.connectClient() sleep(5) self.mcc.publishMessage( resource=ResourceNameEnum.CDA_ACTUATOR_CMD_RESOURCE, msg=payload, qos=qos) sleep(delay) self.mcc.disconnectClient()