def test_connect_refused_error(self, mock_client): """ Test connection refused error, mocked paho part """ conf = {'broker': '127.0.0.1'} mock_client.return_value = MockClientConnectionRefused _client = MqttClient(config=conf, connect_callback=self.mock_callback, message_callback=self.mock_callback) self.assertFalse(_client.connect())
def test_connect_success(self, mock_client): """ Test connecting, mocked paho part """ conf = {'broker': '127.0.0.1'} mock_client.return_value = MockClient _client = MqttClient(config=conf, connect_callback=self.mock_callback, message_callback=self.mock_callback) self.assertTrue(_client.connect())
def test_connect_timeout_error(self, mock_client): """ Test timeout error, mocked paho part """ conf = {'broker': '127.0.0.1'} mock_client.return_value = MockClientTimeoutError _client = MqttClient(config=conf, connect_callback=self.mock_callback, message_callback=self.mock_callback) self.assertFalse(_client.connect())
def test_valid_arguments_1_function_not_callable(self): """ Test bad callbacks """ test_config = {'broker': '127.0.0.1'} callbacks = [self.mock_callback, 'not_callable'] try: MqttClient.valid_arguments(config=test_config, callbacks=callbacks) except IllegalArgumentError: self.assertTrue(True)
def test_valid_arguments_all_invalid(self): """ Test bad callbacks """ test_config = {'not_valid': '127.0.0.1'} callbacks = ['not_callable', 'not_callable'] try: MqttClient.valid_arguments(config=test_config, callbacks=callbacks) except IllegalArgumentError: self.assertTrue(True)
def test_valid_arguments_invalid_config(self): """ Test bad config """ test_config = {'wrong': '127.0.0.1'} callbacks = [self.mock_callback, self.mock_callback] try: MqttClient.valid_arguments(config=test_config, callbacks=callbacks) except IllegalArgumentError: self.assertTrue(True)
def test_publish_fail(self): """ Testing publishing, mocking the actual publish""" conf = {'broker': '127.0.0.1'} _client = MqttClient(config=conf, connect_callback=self.mock_callback, message_callback=self.mock_callback) mock_mqtt_client = mock.PropertyMock( return_value=MockClientPublishFail) type(_client)._mqtt_client = mock_mqtt_client self.assertFalse(_client.publish("test", {'a': 12}))
def test_on_message(self): """ Testing on message, mocking the actual paho code""" mock_msg = MockOnMessage() conf = {'broker': '127.0.0.1'} _client = MqttClient(config=conf, connect_callback=self.mock_callback, message_callback=mock_msg.on_msg_callback) msg = 'test_123' topic = 'test_topic' mock_msg.payload = msg.encode('utf-8') mock_msg.topic = topic _client._on_message(None, None, mock_msg) self.assertEqual(mock_msg.result_payload, msg) self.assertEqual(mock_msg.result_topic, topic)
def test_valid_arguments_correct(self): """ Test valid arguments """ test_config = {'broker': '127.0.0.1'} callbacks = [self.mock_callback, self.mock_callback] self.assertTrue( MqttClient.valid_arguments(config=test_config, callbacks=callbacks))
def __init__(self, queue, thread_event: Event): Thread.__init__(self) self.config: dict = ConfigurationParser().get_config() self.log = Logging(owner=__file__, config=True) self._observer_notify_queue: Queue = Queue(maxsize=100) self._observer_publish_queue: Queue = queue self._thread_ready: Event = thread_event config = self.get_mqtt_config() self.mqtt_client = MqttClient(config=config, connect_callback=self.on_connect, message_callback=self.on_message) if not self.mqtt_client.connect(): # todo: unscribcribe from subject self.log.critical("TODO: Unsubscribe itself form framework")
class MqttGateway(Thread): running = False subscribed_event = ['gcp_state_changed', 'digital_twin'] def __init__(self, queue, thread_event: Event): Thread.__init__(self) self.config: dict = ConfigurationParser().get_config() self.log = Logging(owner=__file__, config=True) self._observer_notify_queue: Queue = Queue(maxsize=100) self._observer_publish_queue: Queue = queue self._thread_ready: Event = thread_event config = self.get_mqtt_config() self.mqtt_client = MqttClient(config=config, connect_callback=self.on_connect, message_callback=self.on_message) if not self.mqtt_client.connect(): # todo: unscribcribe from subject self.log.critical("TODO: Unsubscribe itself form framework") def __del__(self): self.running = False def run(self): self._thread_ready.set() while self.running: queue_item = self._observer_notify_queue.get() if queue_item.event == "digital_twin": self._handle_digital_twin_event(msg=queue_item) def notify(self, msg: ObserverMessage): self._observer_notify_queue.put(item=msg) def get_mqtt_config(self) -> dict: return { 'broker': self.config['mqtt_gateway']['broker_address'], 'port': 1883, 'stay_alive': 60 } def on_connect(self): topics = ['iot/#'] self.mqtt_client.subscribe(topics=topics) self._thread_ready.set() self.running = True def on_message(self, topic: str, payload: str) -> None: self.log.info(f'Received {payload!r} on topic {topic!r}') self._log_mqtt_traffic(topic=topic, payload=payload) message = IotMessage(mqtt_topic=topic, data=payload) if message.is_valid(): handler = self._select_handler(event=message.event) handler(msg=message) else: self.log.warning('The MQTT message is not valid') def _log_mqtt_traffic(self, topic: str, payload: str) -> None: data = { 'timestamp': datetime.now(), 'source': type(self).__name__, 'topic': topic, 'payload': payload } msg = ObserverMessage(event="iot_traffic", data=data) self._observer_publish_queue.put(msg) def _select_handler(self, event: str) -> Callable: handler_map = { 'state': self._handle_state_change, 'telemetry': self._handle_telemetry, 'system': self._handle_system, 'verification': self._handle_verification } return handler_map.get(event, self._unknown_event) def _unknown_event(self, msg: IotMessage) -> None: self.log.warning(f'Unknown event {msg.event} - No action selected') def _handle_state_change(self, msg: IotMessage) -> None: self.log.debug("Handling state event") message = { 'device_id': msg.device_id, 'event_type': msg.event, 'state': msg.payload.get('state') } item = ObserverMessage(event="device_state_changed", data=message) self._observer_publish_queue.put(item) def _handle_telemetry(self, msg: IotMessage) -> None: self.log.debug("Handling telemetry event") message = {'timestamp': datetime.now(), 'device_id': msg.device_id} message.update(msg.payload) item = ObserverMessage(event="device_sensor_data", data=message) self._observer_publish_queue.put(item) def _handle_system(self, msg: IotMessage) -> None: self.log.debug(f"Handling system message from device {msg.device_id}") if msg.device_id != "framework": message = {'device_id': msg.device_id} message.update(msg.payload) item = ObserverMessage(event="digital_twin", data=message, subject="device_status") self._observer_publish_queue.put(item) def _handle_verification(self, msg: IotMessage) -> None: self.log.debug(f"Handling verification event {msg.event}") if msg.payload.get("action") == "ping": self.mqtt_client.publish(topic="iot/devices/system/verification", msg={"action": "pong"}) def _handle_digital_twin_event(self, msg: ObserverMessage): if msg.subject == "poll_devices": self.mqtt_client.publish(topic="iot/devices/framework/system", msg={"event": "poll"})