示例#1
0
 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())
示例#2
0
 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())
示例#3
0
 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())
示例#4
0
 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)
示例#5
0
 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)
示例#6
0
 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)
示例#7
0
 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}))
示例#8
0
 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)
示例#9
0
 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))
示例#10
0
    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")
示例#11
0
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"})