Exemple #1
0
    def setUp(self) -> None:
        self.fiware_header = FiwareHeader(
            service=settings.FIWARE_SERVICE,
            service_path=settings.FIWARE_SERVICEPATH)
        self.service_group_json = ServiceGroup(
            apikey=settings.FIWARE_SERVICEPATH.strip('/'),
            resource="/iot/json")
        self.service_group_ul = ServiceGroup(
            apikey=settings.FIWARE_SERVICEPATH.strip('/'), resource="/iot/d")

        # create a device configuration
        device_attr = DeviceAttribute(name='temperature',
                                      object_id='t',
                                      type="Number")
        device_command = DeviceCommand(name='heater', type="Boolean")

        self.device_json = Device(device_id='my_json_device',
                                  entity_name='my_json_device',
                                  entity_type='Thing',
                                  protocol='IoTA-JSON',
                                  transport='MQTT',
                                  apikey=self.service_group_json.apikey,
                                  attributes=[device_attr],
                                  commands=[device_command])

        self.device_ul = Device(device_id='my_ul_device',
                                entity_name='my_ul_device',
                                entity_type='Thing',
                                protocol='PDI-IoTA-UltraLight',
                                transport='MQTT',
                                apikey=self.service_group_ul.apikey,
                                attributes=[device_attr],
                                commands=[device_command])

        self.mqttc = IoTAMQTTClient()

        def on_connect(mqttc, obj, flags, rc):
            mqttc.logger.info("rc: " + str(rc))

        def on_connect_fail(mqttc, obj):
            mqttc.logger.info("Connect failed")

        def on_publish(mqttc, obj, mid):
            mqttc.logger.info("mid: " + str(mid))

        def on_subscribe(mqttc, obj, mid, granted_qos):
            mqttc.logger.info("Subscribed: " + str(mid) + " " +
                              str(granted_qos))

        def on_log(mqttc, obj, level, string):
            mqttc.logger.info(string)

        self.mqttc.on_connect = on_connect
        self.mqttc.on_connect_fail = on_connect_fail
        self.mqttc.on_publish = on_publish
        self.mqttc.on_subscribe = on_subscribe
        self.mqttc.on_log = on_log
Exemple #2
0
    def __validate_device(self, device: Union[Device, Dict]) -> Device:
        """
        Validates configuration of an IoT Device

        Args:
            device: device model to check on

        Returns:
            Device: validated model

        Raises:
            AssertionError: for faulty configurations
        """
        if isinstance(device, dict):
            device = Device.parse_obj(device)

        assert isinstance(device, Device), "Invalid device configuration!"

        assert device.transport == TransportProtocol.MQTT, \
            "Unsupported transport protocol found in device configuration!"

        if device.apikey in self.service_groups.keys():
            pass
        # check if matching service group is registered
        else:
            msg = "Could not find matching service group! " \
                  "Communication may not work correctly!"
            self.logger.warning(msg=msg)
            warnings.warn(message=msg)

        return device
Exemple #3
0
    def test_metadata(self):
        """
        Test for metadata works but the api of iot agent-json seems not
        working correctly
        Returns:
            None
        """
        metadata = {"accuracy": {"type": "Text",
                                 "value": "+-5%"}}
        attr = DeviceAttribute(name="temperature",
                               object_id="temperature",
                               type="Number",
                               metadata=metadata)
        device = Device(**self.device)
        device.device_id = "device_with_meta"
        device.add_attribute(attribute=attr)
        logger.info(device.json(indent=2))

        with IoTAClient(
                url=settings.IOTA_JSON_URL,
                fiware_header=self.fiware_header) as client:
            client.post_device(device=device)
            logger.info(client.get_device(device_id=device.device_id).json(
                indent=2, exclude_unset=True))

        with ContextBrokerClient(
                url=settings.CB_URL,
                fiware_header=self.fiware_header) as client:
            logger.info(client.get_entity(entity_id=device.entity_name).json(
                indent=2))
Exemple #4
0
    def get_device(self, *, device_id: str) -> Device:
        """
        Returns all the information about a particular device.
        
        Args:
            device_id:
        Raises:
            requests.RequestException, if device does not exist
        Returns:
            Device

        """
        url = urljoin(self.base_url, f'iot/devices/{device_id}')
        headers = self.headers
        try:
            res = self.get(url=url, headers=headers)
            if res.ok:
                return Device.parse_obj(res.json())
            res.raise_for_status()
        except requests.RequestException as err:
            msg = f"Device {device_id} was not found"
            self.log_error(err=err, msg=msg)
            raise
Exemple #5
0
    def update_device(self, *, device: Device, add: bool = True) -> None:
        """
        Updates a device from the device registry.
        Adds, removes attributes from the device entry and changes
        attributes values.
        It does not change device settings (endpoint,..) and only adds
        attributes to the corresponding entity, their it does not
        change any attribute value and does not delete removed attributes

        Args:
            device:
            add (bool): If device not found add it
        Returns:
            None
        """
        url = urljoin(self.base_url, f'iot/devices/{device.device_id}')
        headers = self.headers
        try:
            res = self.put(url=url,
                           headers=headers,
                           json=device.dict(include={
                               'attributes', 'lazy', 'commands',
                               'static_attributes'
                           },
                                            exclude_none=True))
            if res.ok:
                self.logger.info("Device '%s' successfully updated!",
                                 device.device_id)
            elif (res.status_code == 404) & (add is True):
                self.post_device(device=device, update=False)
            else:
                res.raise_for_status()
        except requests.RequestException as err:
            msg = f"Could not update device '{device.device_id}'"
            self.log_error(err=err, msg=msg)
            raise
Exemple #6
0
 def test_device_model(self):
     device = Device(**self.device)
     self.assertEqual(self.device,
                      device.dict(exclude_unset=True))
Exemple #7
0
    def test_patch_device(self):
        """
            Test the methode: patch_device of the iota client
        """

        device = Device(**self.device)
        device.endpoint = "http://test.com"
        device.transport = "MQTT"

        device.add_attribute(DeviceAttribute(
            name="Att1", object_id="o1", type=DataType.STRUCTUREDVALUE))
        device.add_attribute(StaticDeviceAttribute(
            name="Stat1", value="test", type=DataType.STRUCTUREDVALUE))
        device.add_attribute(StaticDeviceAttribute(
            name="Stat2", value="test", type=DataType.STRUCTUREDVALUE))
        device.add_command(DeviceCommand(name="Com1"))

        # use patch_device to post
        self.client.patch_device(device=device)

        cb_client = ContextBrokerClient(url=settings.CB_URL,
                                        fiware_header=self.fiware_header)

        # test if attributes exists correctly
        live_entity = cb_client.get_entity(entity_id=device.entity_name)
        live_entity.get_attribute("Att1")
        live_entity.get_attribute("Com1")
        live_entity.get_attribute("Com1_info")
        live_entity.get_attribute("Com1_status")
        self.assertEqual(live_entity.get_attribute("Stat1").value, "test")

        # change device attributes and update
        device.get_attribute("Stat1").value = "new_test"
        device.delete_attribute(device.get_attribute("Stat2"))
        device.delete_attribute(device.get_attribute("Att1"))
        device.delete_attribute(device.get_attribute("Com1"))
        device.add_attribute(DeviceAttribute(
            name="Att2", object_id="o1", type=DataType.STRUCTUREDVALUE))
        device.add_attribute(StaticDeviceAttribute(
            name="Stat3", value="test3", type=DataType.STRUCTUREDVALUE))
        device.add_command(DeviceCommand(name="Com2"))

        self.client.patch_device(device=device, cb_url=settings.CB_URL)

        # test if update does what it should, for the device. It does not
        # change the entity completely:
        live_entity = cb_client.get_entity(entity_id=device.entity_name)
        with self.assertRaises(KeyError):
            live_entity.get_attribute("Att1")
        with self.assertRaises(KeyError):
            live_entity.get_attribute("Com1_info")
        with self.assertRaises(KeyError):
            live_entity.get_attribute("Stat2")
        self.assertEqual(live_entity.get_attribute("Stat1").value, "new_test")
        live_entity.get_attribute("Stat3")
        live_entity.get_attribute("Com2_info")
        live_entity.get_attribute("Att2")

        # test update where device information were changed
        device_settings = {"endpoint": "http://localhost:7071",
                           "device_id": "new_id",
                           "entity_name": "new_name",
                           "entity_type": "new_type",
                           "timestamp": False,
                           "apikey": "zuiop",
                           "protocol": "HTTP",
                           "transport": "HTTP"}

        for key, value in device_settings.items():
            device.__setattr__(key, value)
            self.client.patch_device(device=device)
            live_device = self.client.get_device(device_id=device.device_id)
            self.assertEqual(live_device.__getattribute__(key), value)
            cb_client.close()
Exemple #8
0
    def test_update_device(self):
        """
        Test the methode: update_device of the iota client
        """

        device = Device(**self.device)
        device.endpoint = "http://test.com"
        device.transport = "MQTT"

        device.add_attribute(DeviceAttribute(
            name="Att1", object_id="o1", type=DataType.STRUCTUREDVALUE))
        device.add_attribute(StaticDeviceAttribute(
            name="Stat1", value="test", type=DataType.STRUCTUREDVALUE))
        device.add_attribute(StaticDeviceAttribute(
            name="Stat2", value="test", type=DataType.STRUCTUREDVALUE))
        device.add_command(DeviceCommand(name="Com1"))

        # use update_device to post
        self.client.update_device(device=device, add=True)

        cb_client = ContextBrokerClient(url=settings.CB_URL,
                                        fiware_header=self.fiware_header)

        # test if attributes exists correctly
        live_entity = cb_client.get_entity(entity_id=device.entity_name)
        live_entity.get_attribute("Att1")
        live_entity.get_attribute("Com1")
        live_entity.get_attribute("Com1_info")
        live_entity.get_attribute("Com1_status")
        self.assertEqual(live_entity.get_attribute("Stat1").value, "test")

        # change device attributes and update
        device.get_attribute("Stat1").value = "new_test"
        device.delete_attribute(device.get_attribute("Stat2"))
        device.delete_attribute(device.get_attribute("Att1"))
        device.delete_attribute(device.get_attribute("Com1"))
        device.add_attribute(DeviceAttribute(
            name="Att2", object_id="o1", type=DataType.STRUCTUREDVALUE))
        device.add_attribute(StaticDeviceAttribute(
            name="Stat3", value="test3", type=DataType.STRUCTUREDVALUE))
        device.add_command(DeviceCommand(name="Com2"))

        # device.endpoint = "http://localhost:8080"
        self.client.update_device(device=device)

        # test if update does what it should, for the device. It does not
        # change the entity completely:

        live_device = self.client.get_device(device_id=device.device_id)

        with self.assertRaises(KeyError):
            live_device.get_attribute("Att1")
        with self.assertRaises(KeyError):
            live_device.get_attribute("Com1_info")
        with self.assertRaises(KeyError):
            live_device.get_attribute("Stat2")
        self.assertEqual(live_device.get_attribute("Stat1").value, "new_test")
        live_device.get_attribute("Stat3")
        live_device.get_command("Com2")
        live_device.get_attribute("Att2")

        cb_client.close()
Exemple #9
0
    def test_deletions(self):
        """
        Test the deletion of a context entity/device if the state is always
        correctly cleared
        """
        self.tearDown()

        device_id = 'device_id'
        entity_id = 'entity_id'

        device = Device(device_id=device_id,
                        entity_name=entity_id,
                        entity_type='Thing2',
                        protocol='IoTA-JSON',
                        transport='HTTP',
                        apikey='filip-iot-test-device')

        cb_client = ContextBrokerClient(url=settings.CB_URL,
                                        fiware_header=self.fiware_header)

        # Test 1: Only delete device
        # delete without optional parameter -> entity needs to continue existing
        self.client.post_device(device=device)
        self.client.delete_device(device_id=device_id, cb_url=settings.CB_URL)
        self.assertTrue(
            len(cb_client.get_entity_list(entity_ids=[entity_id])) == 1)
        cb_client.delete_entity(entity_id=entity_id, entity_type='Thing2')

        # Test 2:Delete device and corresponding entity
        # delete with optional parameter -> entity needs to be deleted
        self.client.post_device(device=device)
        self.client.delete_device(device_id=device_id,
                                  cb_url=settings.CB_URL,
                                  delete_entity=True)
        self.assertTrue(
            len(cb_client.get_entity_list(entity_ids=[entity_id])) == 0)

        # Test 3:Delete device and corresponding entity,
        #        that is linked to multiple devices
        # delete with optional parameter -> entity needs to be deleted
        self.client.post_device(device=device)
        device2 = copy.deepcopy(device)
        device2.device_id = "device_id2"
        self.client.post_device(device=device2)
        self.assertRaises(Exception, self.client.delete_device,
                          device_id=device_id, delete_entity=True)
        self.assertTrue(
            len(cb_client.get_entity_list(entity_ids=[entity_id])) == 1)
        self.client.delete_device(device_id=device2.device_id)

        # Test 4: Only delete entity
        # delete without optional parameter -> device needs to continue existing
        self.client.post_device(device=device)
        cb_client.delete_entity(entity_id=entity_id, entity_type='Thing2')
        self.client.get_device(device_id=device_id)
        self.client.delete_device(device_id=device_id)

        # Test 5: Delete entity, and all devices
        # # delete with optional parameter -> all devices need to be deleted
        self.client.post_device(device=device)
        device2 = copy.deepcopy(device)
        device2.device_id = "device_id2"
        self.client.post_device(device=device2)
        cb_client.delete_entity(entity_id=entity_id, delete_devices=True,
                                entity_type='Thing2',
                                iota_url=settings.IOTA_JSON_URL)
        self.assertEqual(len(self.client.get_device_list()), 0)
Exemple #10
0
class TestMQTTClient(unittest.TestCase):
    """
    Test case for IoTAMQTTClient
    """
    def setUp(self) -> None:
        self.fiware_header = FiwareHeader(
            service=settings.FIWARE_SERVICE,
            service_path=settings.FIWARE_SERVICEPATH)
        self.service_group_json = ServiceGroup(
            apikey=settings.FIWARE_SERVICEPATH.strip('/'),
            resource="/iot/json")
        self.service_group_ul = ServiceGroup(
            apikey=settings.FIWARE_SERVICEPATH.strip('/'), resource="/iot/d")

        # create a device configuration
        device_attr = DeviceAttribute(name='temperature',
                                      object_id='t',
                                      type="Number")
        device_command = DeviceCommand(name='heater', type="Boolean")

        self.device_json = Device(device_id='my_json_device',
                                  entity_name='my_json_device',
                                  entity_type='Thing',
                                  protocol='IoTA-JSON',
                                  transport='MQTT',
                                  apikey=self.service_group_json.apikey,
                                  attributes=[device_attr],
                                  commands=[device_command])

        self.device_ul = Device(device_id='my_ul_device',
                                entity_name='my_ul_device',
                                entity_type='Thing',
                                protocol='PDI-IoTA-UltraLight',
                                transport='MQTT',
                                apikey=self.service_group_ul.apikey,
                                attributes=[device_attr],
                                commands=[device_command])

        self.mqttc = IoTAMQTTClient()

        def on_connect(mqttc, obj, flags, rc):
            mqttc.logger.info("rc: " + str(rc))

        def on_connect_fail(mqttc, obj):
            mqttc.logger.info("Connect failed")

        def on_publish(mqttc, obj, mid):
            mqttc.logger.info("mid: " + str(mid))

        def on_subscribe(mqttc, obj, mid, granted_qos):
            mqttc.logger.info("Subscribed: " + str(mid) + " " +
                              str(granted_qos))

        def on_log(mqttc, obj, level, string):
            mqttc.logger.info(string)

        self.mqttc.on_connect = on_connect
        self.mqttc.on_connect_fail = on_connect_fail
        self.mqttc.on_publish = on_publish
        self.mqttc.on_subscribe = on_subscribe
        self.mqttc.on_log = on_log

    def test_original_functionality(self):
        """
        demonstrate normal client behavior
        For additional examples on how to use the client please check:
        https://github.com/eclipse/paho.mqtt.python/tree/master/examples
        define callbacks methods"""
        first_topic = f"/filip/{settings.FIWARE_SERVICEPATH.strip('/')}/first"
        second_topic = f"/filip/{settings.FIWARE_SERVICEPATH.strip('/')}/second"
        first_payload = "filip_test_1"
        second_payload = "filip_test_2"

        def on_message_first(mqttc, obj, msg, properties=None):
            self.assertEqual(msg.payload.decode('utf-8'), first_payload)

        def on_message_second(mqttc, obj, msg, properties=None):
            self.assertEqual(msg.payload.decode('utf-8'), second_payload)

        self.mqttc.message_callback_add(sub=first_topic,
                                        callback=on_message_first)
        self.mqttc.message_callback_add(sub=second_topic,
                                        callback=on_message_second)
        mqtt_broker_url = urlparse(settings.MQTT_BROKER_URL)

        self.mqttc.connect(host=mqtt_broker_url.hostname,
                           port=mqtt_broker_url.port,
                           keepalive=60,
                           bind_address="",
                           bind_port=0,
                           clean_start=MQTT_CLEAN_START_FIRST_ONLY,
                           properties=None)
        self.mqttc.subscribe(topic=first_topic)

        # create a non blocking loop
        self.mqttc.loop_start()
        self.mqttc.publish(topic=first_topic, payload="filip_test")

        # add additional subscription to connection
        self.mqttc.subscribe(topic=second_topic)
        self.mqttc.publish(topic=second_topic, payload="filip_test")

        # remove subscriptions and callbacks
        self.mqttc.message_callback_remove(first_topic)
        self.mqttc.message_callback_remove(second_topic)
        self.mqttc.unsubscribe(first_topic)
        self.mqttc.unsubscribe(second_topic)

        # stop network loop and disconnect cleanly
        self.mqttc.loop_stop()
        self.mqttc.disconnect()

    def test_init(self):
        devices = [self.device_json, self.device_ul]
        mqttc = IoTAMQTTClient(devices=devices,
                               service_groups=[self.service_group_json])
        self.assertListEqual(mqttc.devices, devices)

    def test_service_groups(self):
        self.mqttc.add_service_group(service_group=self.service_group_json)
        with self.assertRaises(AssertionError):
            self.mqttc.add_service_group(service_group="SomethingRandom")
        with self.assertRaises(ValueError):
            self.mqttc.add_service_group(
                service_group=self.service_group_json.dict())

        self.assertEqual(
            self.service_group_json,
            self.mqttc.get_service_group(self.service_group_json.apikey))

        self.mqttc.update_service_group(service_group=self.service_group_json)

        with self.assertRaises(KeyError):
            self.mqttc.update_service_group(
                service_group=self.service_group_json.copy(
                    update={'apikey': 'someOther'}))

        with self.assertRaises(KeyError):
            self.mqttc.delete_service_group(apikey="SomethingRandom")

        self.mqttc.delete_service_group(apikey=self.service_group_json.apikey)

    def test_devices(self):
        with self.assertRaises(ValueError):
            self.mqttc.devices = [self.device_ul, self.device_ul]

        self.mqttc.add_device(device=self.device_json)
        with self.assertRaises(ValueError):
            self.mqttc.add_device(device=self.device_json)
        self.mqttc.get_device(self.device_json.device_id)

        self.mqttc.update_device(device=self.device_json)
        with self.assertRaises(KeyError):
            self.mqttc.update_device(device=self.device_json.copy(
                update={'device_id': "somethingRandom"}))

        self.mqttc.delete_device(device_id=self.device_json.device_id)

    @clean_test(fiware_service=settings.FIWARE_SERVICE,
                fiware_servicepath=settings.FIWARE_SERVICEPATH,
                cb_url=settings.CB_URL,
                iota_url=settings.IOTA_JSON_URL)
    def test_add_command_callback_json(self):
        """
        Test for receiving commands for a specific device
        Returns:
            None
        """
        for group in self.mqttc.service_groups:
            self.mqttc.delete_service_group(group.apikey)

        for device in self.mqttc.devices:
            self.mqttc.delete_device(device.device_id)

        def on_command(client, obj, msg):
            apikey, device_id, payload = \
                client.get_encoder(PayloadProtocol.IOTA_JSON).decode_message(
                    msg=msg)

            # acknowledge a command. Here command are usually single
            # messages. The first key is equal to the commands name.
            client.publish(device_id=device_id,
                           command_name=next(iter(payload)),
                           payload=payload)

        self.mqttc.add_service_group(self.service_group_json)
        self.mqttc.add_device(self.device_json)
        self.mqttc.add_command_callback(device_id=self.device_json.device_id,
                                        callback=on_command)

        from filip.clients.ngsi_v2 import HttpClient, HttpClientConfig
        httpc_config = HttpClientConfig(cb_url=settings.CB_URL,
                                        iota_url=settings.IOTA_JSON_URL)
        httpc = HttpClient(fiware_header=self.fiware_header,
                           config=httpc_config)
        httpc.iota.post_group(service_group=self.service_group_json,
                              update=True)
        httpc.iota.post_device(device=self.device_json, update=True)

        mqtt_broker_url = urlparse(settings.MQTT_BROKER_URL)

        self.mqttc.connect(host=mqtt_broker_url.hostname,
                           port=mqtt_broker_url.port,
                           keepalive=60,
                           bind_address="",
                           bind_port=0,
                           clean_start=MQTT_CLEAN_START_FIRST_ONLY,
                           properties=None)
        self.mqttc.subscribe()

        entity = httpc.cb.get_entity(entity_id=self.device_json.device_id,
                                     entity_type=self.device_json.entity_type)
        context_command = NamedCommand(name=self.device_json.commands[0].name,
                                       value=False)
        self.mqttc.loop_start()

        httpc.cb.post_command(entity_id=entity.id,
                              entity_type=entity.type,
                              command=context_command)

        time.sleep(2)
        # close the mqtt listening thread
        self.mqttc.loop_stop()
        # disconnect the mqtt device
        self.mqttc.disconnect()

        entity = httpc.cb.get_entity(entity_id=self.device_json.device_id,
                                     entity_type=self.device_json.entity_type)

        # The main part of this test, for all this setup was done
        self.assertEqual("OK", entity.heater_status.value)

    @clean_test(fiware_service=settings.FIWARE_SERVICE,
                fiware_servicepath=settings.FIWARE_SERVICEPATH,
                cb_url=settings.CB_URL,
                iota_url=settings.IOTA_JSON_URL)
    def test_publish_json(self):
        """
        Test for receiving commands for a specific device
        Returns:
            None
        """
        for group in self.mqttc.service_groups:
            self.mqttc.delete_service_group(group.apikey)

        for device in self.mqttc.devices:
            self.mqttc.delete_device(device.device_id)

        self.mqttc.add_service_group(self.service_group_json)
        self.mqttc.add_device(self.device_json)

        from filip.clients.ngsi_v2 import HttpClient, HttpClientConfig
        httpc_config = HttpClientConfig(cb_url=settings.CB_URL,
                                        iota_url=settings.IOTA_JSON_URL)
        httpc = HttpClient(fiware_header=self.fiware_header,
                           config=httpc_config)
        httpc.iota.post_group(service_group=self.service_group_json,
                              update=True)
        httpc.iota.post_device(device=self.device_json, update=True)

        mqtt_broker_url = urlparse(settings.MQTT_BROKER_URL)

        self.mqttc.connect(host=mqtt_broker_url.hostname,
                           port=mqtt_broker_url.port,
                           keepalive=60,
                           bind_address="",
                           bind_port=0,
                           clean_start=MQTT_CLEAN_START_FIRST_ONLY,
                           properties=None)
        self.mqttc.loop_start()

        payload = randrange(0, 100, 1) / 1000
        self.mqttc.publish(
            device_id=self.device_json.device_id,
            payload={self.device_json.attributes[0].object_id: payload})
        time.sleep(1)
        entity = httpc.cb.get_entity(entity_id=self.device_json.device_id,
                                     entity_type=self.device_json.entity_type)
        self.assertEqual(payload, entity.temperature.value)

        payload = randrange(0, 100, 1) / 1000
        self.mqttc.publish(device_id=self.device_json.device_id,
                           attribute_name="temperature",
                           payload=payload)
        time.sleep(1)
        entity = httpc.cb.get_entity(entity_id=self.device_json.device_id,
                                     entity_type=self.device_json.entity_type)
        self.assertEqual(payload, entity.temperature.value)

        # These test do currently not workt due to time stamp parsing
        # self.mqttc.publish(device_id=self.device_json.device_id,
        #                    payload={self.device_json.attributes[
        #                   0].object_id: 50},
        #                    timestamp=True)
        # time.sleep(1)
        # entity = httpc.cb.get_entity(entity_id=self.device_json.device_id,
        #                              entity_type=self.device_json.entity_type)
        # self.assertEqual(50, entity.temperature.value)
        #
        # from datetime import datetime, timedelta
        # timestamp = datetime.now() + timedelta(days=1)
        # timestamp = timestamp.astimezone().isoformat()
        # self.mqttc.publish(device_id=self.device_json.device_id,
        #                    payload={self.device_json.attributes[
        #                   0].object_id: 60,
        #                             'timeInstant': timestamp})
        # time.sleep(1)
        # entity = httpc.cb.get_entity(entity_id=self.device_json.device_id,
        #                              entity_type=self.device_json.entity_type)
        # self.assertEqual(60, entity.temperature.value)
        # self.assertEqual(timestamp, entity.TimeInstant.value)
        #
        # print(entity.json(indent=2))

        # close the mqtt listening thread
        self.mqttc.loop_stop()
        # disconnect the mqtt device
        self.mqttc.disconnect()

    @clean_test(fiware_service=settings.FIWARE_SERVICE,
                fiware_servicepath=settings.FIWARE_SERVICEPATH,
                cb_url=settings.CB_URL,
                iota_url=settings.IOTA_UL_URL)
    def test_add_command_callback_ultralight(self):
        """
        Test for receiving commands for a specific device
        Returns:
            None
        """
        for group in self.mqttc.service_groups:
            self.mqttc.delete_service_group(group.apikey)

        for device in self.mqttc.devices:
            self.mqttc.delete_device(device.device_id)

        def on_command(client, obj, msg):
            apikey, device_id, payload = \
                client.get_encoder(PayloadProtocol.IOTA_UL).decode_message(
                    msg=msg)

            # acknowledge a command. Here command are usually single
            # messages. The first key is equal to the commands name.
            client.publish(device_id=device_id,
                           command_name=next(iter(payload)),
                           payload={'heater': True})

        self.mqttc.add_service_group(self.service_group_ul)
        self.mqttc.add_device(self.device_ul)
        self.mqttc.add_command_callback(device_id=self.device_ul.device_id,
                                        callback=on_command)

        from filip.clients.ngsi_v2 import HttpClient, HttpClientConfig
        httpc_config = HttpClientConfig(cb_url=settings.CB_URL,
                                        iota_url=settings.IOTA_UL_URL)
        httpc = HttpClient(fiware_header=self.fiware_header,
                           config=httpc_config)
        httpc.iota.post_group(service_group=self.service_group_ul)
        httpc.iota.post_device(device=self.device_ul, update=True)

        mqtt_broker_url = urlparse(settings.MQTT_BROKER_URL)

        self.mqttc.connect(host=mqtt_broker_url.hostname,
                           port=mqtt_broker_url.port,
                           keepalive=60,
                           bind_address="",
                           bind_port=0,
                           clean_start=MQTT_CLEAN_START_FIRST_ONLY,
                           properties=None)
        self.mqttc.subscribe()

        entity = httpc.cb.get_entity(entity_id=self.device_ul.device_id,
                                     entity_type=self.device_ul.entity_type)
        context_command = NamedCommand(name=self.device_ul.commands[0].name,
                                       value=False)
        self.mqttc.loop_start()

        httpc.cb.post_command(entity_id=entity.id,
                              entity_type=entity.type,
                              command=context_command)

        time.sleep(5)
        # close the mqtt listening thread
        self.mqttc.loop_stop()
        # disconnect the mqtt device
        self.mqttc.disconnect()

        entity = httpc.cb.get_entity(entity_id=self.device_ul.device_id,
                                     entity_type=self.device_ul.entity_type)

        # The main part of this test, for all this setup was done
        self.assertEqual("OK", entity.heater_status.value)

    @clean_test(fiware_service=settings.FIWARE_SERVICE,
                fiware_servicepath=settings.FIWARE_SERVICEPATH,
                cb_url=settings.CB_URL,
                iota_url=settings.IOTA_UL_URL)
    def test_publish_ultralight(self):
        """
        Test for receiving commands for a specific device
        Returns:
            None
        """
        for group in self.mqttc.service_groups:
            self.mqttc.delete_service_group(group.apikey)

        for device in self.mqttc.devices:
            self.mqttc.delete_device(device.device_id)

        self.mqttc.add_service_group(self.service_group_ul)
        self.mqttc.add_device(self.device_ul)

        from filip.clients.ngsi_v2 import HttpClient, HttpClientConfig
        httpc_config = HttpClientConfig(cb_url=settings.CB_URL,
                                        iota_url=settings.IOTA_UL_URL)
        httpc = HttpClient(fiware_header=self.fiware_header,
                           config=httpc_config)
        httpc.iota.post_group(service_group=self.service_group_ul, update=True)
        httpc.iota.post_device(device=self.device_ul, update=True)

        time.sleep(0.5)

        mqtt_broker_url = urlparse(settings.MQTT_BROKER_URL)

        self.mqttc.connect(host=mqtt_broker_url.hostname,
                           port=mqtt_broker_url.port,
                           keepalive=60,
                           bind_address="",
                           bind_port=0,
                           clean_start=MQTT_CLEAN_START_FIRST_ONLY,
                           properties=None)
        self.mqttc.loop_start()

        payload = randrange(0, 100, 1) / 1000
        self.mqttc.publish(
            device_id=self.device_ul.device_id,
            payload={self.device_ul.attributes[0].object_id: payload})
        time.sleep(1)
        entity = httpc.cb.get_entity(entity_id=self.device_ul.device_id,
                                     entity_type=self.device_ul.entity_type)
        self.assertEqual(payload, entity.temperature.value)

        payload = randrange(0, 100, 1) / 1000
        self.mqttc.publish(device_id=self.device_ul.device_id,
                           attribute_name="temperature",
                           payload=payload)
        time.sleep(1)
        entity = httpc.cb.get_entity(entity_id=self.device_ul.device_id,
                                     entity_type=self.device_ul.entity_type)
        self.assertEqual(payload, entity.temperature.value)

        # These test do currently not workt due to time stamp parsing
        # self.mqttc.publish(device_id=self.device_ul.device_id,
        #                    payload={self.device_ul.attributes[0].object_id:
        #                   50},
        #                    timestamp=True)
        # time.sleep(1)
        # entity = httpc.cb.get_entity(entity_id=self.device_ul.device_id,
        #                              entity_type=self.device_ul.entity_type)
        # self.assertEqual(50, entity.temperature.value)
        #
        # from datetime import datetime, timedelta
        # timestamp = datetime.now() + timedelta(days=1)
        # timestamp = timestamp.astimezone().isoformat()
        # self.mqttc.publish(device_id=self.device_ul.device_id,
        #                    payload={self.device_ul.attributes[0].object_id:
        #                    60,
        #                             'timeInstant': timestamp})
        # time.sleep(1)
        # entity = httpc.cb.get_entity(entity_id=self.device_ul.device_id,
        #                              entity_type=self.device_ul.entity_type)
        # self.assertEqual(60, entity.temperature.value)
        # self.assertEqual(timestamp, entity.TimeInstant.value)
        #
        # print(entity.json(indent=2))

        # close the mqtt listening thread
        self.mqttc.loop_stop()
        # disconnect the mqtt device
        self.mqttc.disconnect()

    def tearDown(self) -> None:
        """
        Cleanup test server
        """
        clear_all(fiware_header=self.fiware_header,
                  cb_url=settings.CB_URL,
                  iota_url=[settings.IOTA_JSON_URL, settings.IOTA_UL_URL])
Exemple #11
0
    def test_fiware_safe_fields(self):
        """
        Tests all fields of models/ngsi_v2/iot.py that have a regex to
        be FIWARE safe
        Returns:
            None
        """

        from pydantic.error_wrappers import ValidationError

        valid_strings: List[str] = ["name", "test123", "3_:strange-Name!"]
        invalid_strings: List[str] = [
            "my name", "Test?", "#False", "/notvalid"
        ]

        special_strings: List[str] = ["id", "type", "geo:location"]

        # Test if all needed fields, detect all invalid strings
        for string in invalid_strings:
            self.assertRaises(ValidationError,
                              IoTABaseAttribute,
                              name=string,
                              type="name",
                              entity_name="name",
                              entity_type="name")
            self.assertRaises(ValidationError,
                              IoTABaseAttribute,
                              name="name",
                              type=string,
                              entity_name="name",
                              entity_type="name")
            self.assertRaises(ValidationError,
                              IoTABaseAttribute,
                              name="name",
                              type="name",
                              entity_name=string,
                              entity_type="name")
            self.assertRaises(ValidationError,
                              IoTABaseAttribute,
                              name="name",
                              type="name",
                              entity_name="name",
                              entity_type=string)

            self.assertRaises(ValidationError,
                              DeviceCommand,
                              name=string,
                              type="name")
            self.assertRaises(ValidationError,
                              ServiceGroup,
                              entity_type=string,
                              resource="",
                              apikey="")

            self.assertRaises(ValidationError,
                              Device,
                              device_id="",
                              entity_name=string,
                              entity_type="name",
                              transport=TransportProtocol.HTTP)
            self.assertRaises(ValidationError,
                              Device,
                              device_id="",
                              entity_name="name",
                              entity_type=string,
                              transport=TransportProtocol.HTTP)

        # Test if all needed fields, do not trow wrong errors
        for string in valid_strings:
            IoTABaseAttribute(name=string,
                              type=string,
                              entity_name=string,
                              entity_type=string)
            DeviceCommand(name=string, type="name")
            ServiceGroup(entity_type=string, resource="", apikey="")
            Device(device_id="",
                   entity_name=string,
                   entity_type=string,
                   transport=TransportProtocol.HTTP)

        # Test for the special-string protected field if all strings are blocked
        for string in special_strings:
            with self.assertRaises(ValidationError):
                IoTABaseAttribute(name=string,
                                  type="name",
                                  entity_name="name",
                                  entity_type="name")
            with self.assertRaises(ValidationError):
                IoTABaseAttribute(name="name",
                                  type=string,
                                  entity_name="name",
                                  entity_type="name")
            with self.assertRaises(ValidationError):
                DeviceCommand(name=string, type="name")

        # Test for the normal protected field if all strings are allowed
        for string in special_strings:
            IoTABaseAttribute(name="name",
                              type="name",
                              entity_name=string,
                              entity_type=string)
            ServiceGroup(entity_type=string, resource="", apikey="")
            Device(device_id="",
                   entity_name=string,
                   entity_type=string,
                   transport=TransportProtocol.HTTP)
    # ## 1.2 Device configuration
    #
    service_group_json = ServiceGroup(apikey=SERVICE_PATH.strip('/'),
                                      resource="/iot/json")
    service_group_ul = ServiceGroup(apikey=SERVICE_PATH.strip('/'),
                                    resource="/iot/d")

    device_attr = DeviceAttribute(name='temperature',
                                  object_id='t',
                                  type="Number")
    device_command = DeviceCommand(name='heater', type="Boolean")

    device_json = Device(device_id='my_json_device',
                         entity_name='my_json_device',
                         entity_type='Thing',
                         protocol='IoTA-JSON',
                         transport='MQTT',
                         apikey=service_group_json.apikey,
                         attributes=[device_attr],
                         commands=[device_command])

    device_ul = Device(device_id='my_ul_device',
                       entity_name='my_ul_device',
                       entity_type='Thing',
                       protocol='PDI-IoTA-UltraLight',
                       transport='MQTT',
                       apikey=service_group_ul.apikey,
                       attributes=[device_attr],
                       commands=[device_command])

    # ## 1.3 IoTAMQTTClient
    #
    #  post it to the IoT-Agent. It should be mapped to the `type` heater
    # create the simtime attribute and add during device creation
    t_sim = DeviceAttribute(name='simtime',
                            object_id='t_sim',
                            type="Number")

    # ToDo: create the command attribute of name `heater_on` (currently it is
    #  not possible to add metadata here)
    cmd = DeviceCommand(name="heater_on",
                        type=DataType.BOOLEAN)

    # ToDo: create the device configuration and send it to the server
    heater = Device(device_id="device:003",
                    entity_name="urn:ngsi-ld:Heater:001",
                    entity_type="Heater",
                    apikey=APIKEY,
                    attributes=[t_sim],
                    commands=[cmd],
                    transport='MQTT',
                    protocol='IoTA-JSON')

    iotac.post_device(device=heater)

    # ToDo: Check the entity that corresponds to your device
    heater_entity = cbc.get_entity(entity_id=heater.entity_name,
                                   entity_type=heater.entity_type)
    print(f"Your device entity before running the simulation: \n "
          f"{heater_entity.json(indent=2)}")

    # create a MQTTv5 client with paho-mqtt and the known groups and devices.
    mqttc = IoTAMQTTClient(protocol=mqtt.MQTTv5,
                           devices=[weather_station,
    # Create a service group and add it to your
    service_group = ServiceGroup(apikey=APIKEY, resource="/iot/json")

    # ToDo: create two IoTA-MQTT devices for the weather station and the zone
    #  temperature sensor. Also add the simulation time as `active attribute`
    #  to each device!
    #
    # create the weather station device
    # create the simtime attribute and add during device creation
    t_sim = DeviceAttribute(name='simtime', object_id='t_sim', type="Number")

    weather_station = Device(device_id='device:001',
                             entity_name='urn:ngsi-ld:WeatherStation:001',
                             entity_type='WeatherStation',
                             protocol='IoTA-JSON',
                             transport='MQTT',
                             apikey=APIKEY,
                             attributes=[t_sim],
                             commands=[])

    # create a temperature attribute and add it via the api of the
    # `device`-model. Use the 't_amb' as `object_id`. `object_id` specifies
    # what key will be used in the MQTT Message payload
    t_amb = DeviceAttribute(name='temperature',
                            object_id='t_amb',
                            type="Number")

    weather_station.add_attribute(t_amb)

    # ToDo: create the zone temperature device add the t_sim attribute upon
    #  creation
Exemple #15
0
    def test_command_with_mqtt(self):
        """
        Test if a command can be send to a device in FIWARE

        To test this a virtual device is created and provisioned to FIWARE and
        a hosted MQTT Broker

        This test only works if the address of a running MQTT Broker is given in
        the environment ('MQTT_BROKER_URL')

        The main part of this test was taken out of the iot_mqtt_example, see
        there for a complete documentation
        """
        mqtt_broker_url = settings.MQTT_BROKER_URL

        device_attr1 = DeviceAttribute(name='temperature',
                                       object_id='t',
                                       type="Number",
                                       metadata={
                                           "unit":
                                               {"type": "Unit",
                                                "value": {
                                                    "name": {
                                                        "type": "Text",
                                                        "value": "degree "
                                                                 "Celsius"
                                                    }
                                                }}
                                       })

        # creating a static attribute that holds additional information
        static_device_attr = StaticDeviceAttribute(name='info',
                                                   type="Text",
                                                   value="Filip example for "
                                                         "virtual IoT device")
        # creating a command that the IoT device will liston to
        device_command = DeviceCommand(name='heater', type="Boolean")

        device = Device(device_id='MyDevice',
                        entity_name='MyDevice',
                        entity_type='Thing2',
                        protocol='IoTA-JSON',
                        transport='MQTT',
                        apikey=settings.FIWARE_SERVICEPATH.strip('/'),
                        attributes=[device_attr1],
                        static_attributes=[static_device_attr],
                        commands=[device_command])

        device_attr2 = DeviceAttribute(name='humidity',
                                       object_id='h',
                                       type="Number",
                                       metadata={
                                           "unitText":
                                               {"value": "percent",
                                                "type": "Text"}})

        device.add_attribute(attribute=device_attr2)

        # Send device configuration to FIWARE via the IoT-Agent. We use the
        # general ngsiv2 httpClient for this.
        service_group = ServiceGroup(
            service=self.fiware_header.service,
            subservice=self.fiware_header.service_path,
            apikey=settings.FIWARE_SERVICEPATH.strip('/'),
            resource='/iot/json')

        # create the Http client node that once sent the device cannot be posted
        # again and you need to use the update command
        config = HttpClientConfig(cb_url=settings.CB_URL,
                                  iota_url=settings.IOTA_JSON_URL)
        client = HttpClient(fiware_header=self.fiware_header, config=config)
        client.iota.post_group(service_group=service_group, update=True)
        client.iota.post_device(device=device, update=True)

        time.sleep(0.5)

        # check if the device is correctly configured. You will notice that
        # unfortunately the iot API does not return all the metadata. However,
        # it will still appear in the context-entity
        device = client.iota.get_device(device_id=device.device_id)

        # check if the data entity is created in the context broker
        entity = client.cb.get_entity(entity_id=device.device_id,
                                      entity_type=device.entity_type)

        # create a mqtt client that we use as representation of an IoT device
        # following the official documentation of Paho-MQTT.
        # https://www.eclipse.org/paho/index.php?page=clients/python/
        # docs/index.php

        # The callback for when the mqtt client receives a CONNACK response from
        # the server. All callbacks need to have this specific arguments,
        # Otherwise the client will not be able to execute them.
        def on_connect(client, userdata, flags, reasonCode, properties=None):
            client.subscribe(f"/{device.apikey}/{device.device_id}/cmd")

        # Callback when the command topic is succesfully subscribed
        def on_subscribe(client, userdata, mid, granted_qos, properties=None):
            pass

        # NOTE: We need to use the apikey of the service-group to send the
        # message to the platform
        def on_message(client, userdata, msg):
            data = json.loads(msg.payload)
            res = {k: v for k, v in data.items()}
            client.publish(topic=f"/json/{service_group.apikey}"
                                 f"/{device.device_id}/cmdexe",
                           payload=json.dumps(res))

        def on_disconnect(client, userdata, reasonCode, properties=None):
            pass

        mqtt_client = mqtt.Client(client_id="filip-test",
                                  userdata=None,
                                  protocol=mqtt.MQTTv5,
                                  transport="tcp")

        # add our callbacks to the client
        mqtt_client.on_connect = on_connect
        mqtt_client.on_subscribe = on_subscribe
        mqtt_client.on_message = on_message
        mqtt_client.on_disconnect = on_disconnect

        # extract the form the environment
        mqtt_broker_url = urlparse(mqtt_broker_url)

        mqtt_client.connect(host=mqtt_broker_url.hostname,
                            port=mqtt_broker_url.port,
                            keepalive=60,
                            bind_address="",
                            bind_port=0,
                            clean_start=mqtt.MQTT_CLEAN_START_FIRST_ONLY,
                            properties=None)
        # create a non-blocking thread for mqtt communication
        mqtt_client.loop_start()

        for attr in device.attributes:
            mqtt_client.publish(
                topic=f"/json/{service_group.apikey}/{device.device_id}/attrs",
                payload=json.dumps({attr.object_id: random.randint(0, 9)}))

        time.sleep(5)
        entity = client.cb.get_entity(entity_id=device.device_id,
                                      entity_type=device.entity_type)

        # create and send a command via the context broker
        context_command = NamedCommand(name=device_command.name,
                                       value=False)
        client.cb.post_command(entity_id=entity.id,
                               entity_type=entity.type,
                               command=context_command)

        time.sleep(5)
        # check the entity the command attribute should now show OK
        entity = client.cb.get_entity(entity_id=device.device_id,
                                      entity_type=device.entity_type)

        # The main part of this test, for all this setup was done
        self.assertEqual("OK", entity.heater_status.value)

        # close the mqtt listening thread
        mqtt_client.loop_stop()
        # disconnect the mqtt device
        mqtt_client.disconnect()
Exemple #16
0
    def test_device_endpoints(self):
        """
        Test device creation
        """
        with IoTAClient(
                url=settings.IOTA_JSON_URL,
                fiware_header=self.fiware_header) as client:
            client.get_device_list()
            device = Device(**self.device)

            attr = DeviceAttribute(name='temperature',
                                   object_id='t',
                                   type='Number',
                                   entity_name='test')
            attr_command = DeviceCommand(name='open')
            attr_lazy = LazyDeviceAttribute(name='pressure',
                                            object_id='p',
                                            type='Text',
                                            entity_name='pressure')
            attr_static = StaticDeviceAttribute(name='hasRoom',
                                                type='Relationship',
                                                value='my_partner_id')
            device.add_attribute(attr)
            device.add_attribute(attr_command)
            device.add_attribute(attr_lazy)
            device.add_attribute(attr_static)

            client.post_device(device=device)
            device_res = client.get_device(device_id=device.device_id)
            self.assertEqual(device.dict(exclude={'service',
                                                  'service_path',
                                                  'timezone'}),
                             device_res.dict(exclude={'service',
                                                      'service_path',
                                                      'timezone'}))
            self.assertEqual(self.fiware_header.service, device_res.service)
            self.assertEqual(self.fiware_header.service_path,
                             device_res.service_path)
    static_device_attr = StaticDeviceAttribute(name='info',
                                               type="Text",
                                               value="Filip example for "
                                               "virtual IoT device")
    # creating a command that the IoT device will liston to
    device_command = DeviceCommand(name='heater')

    # NOTE: You need to know that if you define an apikey for a single device it
    # will be only used for outgoing traffic. This is does not become very clear
    # in the official documentation.
    # https://fiware-iotagent-json.readthedocs.io/en/latest/usermanual/index.html
    device = Device(device_id='MyDevice',
                    entity_name='MyDevice',
                    entity_type='Thing2',
                    protocol='IoTA-JSON',
                    transport='MQTT',
                    apikey=DEVICE_APIKEY,
                    attributes=[device_attr1],
                    static_attributes=[static_device_attr],
                    commands=[device_command])

    # You can also add additional attributes via the Device API
    device_attr2 = DeviceAttribute(
        name='humidity',
        object_id='h',
        type="Number",
        metadata={"unitText": {
            "value": "percent",
            "type": "Text"
        }})
Exemple #18
0
    def patch_device(self,
                     device: Device,
                     patch_entity: bool = True,
                     cb_url: AnyHttpUrl = settings.CB_URL) -> None:
        """
        Updates a device state in Fiware, if the device does not exists it
        is created, else its values are updated.
        If the device settings (endpoint,..) were changed the device and
        entity are deleted and re-added.

        If patch_entity is true the corresponding entity in the ContextBroker is
        also correctly updated. Else only new attributes are added there.

        Args:
            device (Device): Device to be posted to /updated in Fiware
            patch_entity (bool): If true the corresponding entity is
                completely synced
            cb_url (AnyHttpUrl): Url of the ContextBroker where the entity is
                found

        Returns:
            None
        """

        try:
            live_device = self.get_device(device_id=device.device_id)
        except requests.RequestException:
            # device does not exist yet, post it
            self.post_device(device=device)
            return

        # if the device settings were changed we need to delete the device
        # and repost it
        settings_dict = {
            "device_id", "service", "service_path", "entity_name",
            "entity_type", "timestamp", "apikey", "endpoint", "protocol",
            "transport", "expressionLanguage"
        }
        import json
        live_settings = live_device.dict(include=settings_dict)
        new_settings = device.dict(include=settings_dict)

        if not live_settings == new_settings:
            self.delete_device(device_id=device.device_id,
                               delete_entity=True,
                               force_entity_deletion=True)
            self.post_device(device=device)
            return

        # We are at a state where the device exists, but only attributes were
        # changed.
        # we need to update the device, and the context entry separately,
        # as update device only takes over a part of the changes to the
        # ContextBroker.

        # update device
        self.update_device(device=device)

        # update context entry
        # 1. build context entity from information in device
        # 2. patch it
        from filip.models.ngsi_v2.context import \
            ContextEntity, NamedContextAttribute

        def build_context_entity_from_device(device: Device) -> ContextEntity:
            from filip.models.base import DataType
            entity = ContextEntity(id=device.entity_name,
                                   type=device.entity_type)

            for command in device.commands:
                entity.add_attributes([
                    # Command attribute will be registered by the device_update
                    NamedContextAttribute(name=f"{command.name}_info",
                                          type=DataType.COMMAND_RESULT),
                    NamedContextAttribute(name=f"{command.name}_status",
                                          type=DataType.COMMAND_STATUS)
                ])
            for attribute in device.attributes:
                entity.add_attributes([
                    NamedContextAttribute(name=attribute.name,
                                          type=DataType.STRUCTUREDVALUE,
                                          metadata=attribute.metadata)
                ])
            for static_attribute in device.static_attributes:
                entity.add_attributes([
                    NamedContextAttribute(name=static_attribute.name,
                                          type=static_attribute.type,
                                          value=static_attribute.value,
                                          metadata=static_attribute.metadata)
                ])
            return entity

        if patch_entity:
            from filip.clients.ngsi_v2 import ContextBrokerClient
            with ContextBrokerClient(
                    url=cb_url, fiware_header=self.fiware_headers) as client:
                client.patch_entity(
                    entity=build_context_entity_from_device(device))
Exemple #19
0
        "entity_name": "sensor1",
        "entity_type": "Sensor",
        "timezone": 'Europe/Berlin',
        "timestamp": True,
        "apikey": "1234",
        "protocol": "IoTA-UL",
        "transport": "MQTT",
        "lazy": [],
        "commands": [],
        "attributes": [],
        "static_attributes": [],
        "internal_attributes": [],
        "explicitAttrs": False,
        "ngsiVersion": "v2"
    }
    device1 = Device(**example_device)

    # Direct Parameters:
    device2 = Device(device_id="sensor009",
                     service=SERVICE,
                     service_path=SERVICE_PATH,
                     entity_name="sensor2",
                     entity_type="Sensor",
                     transport=TransportProtocol.HTTP,
                     endpoint="http://localhost:1234")

    # ## 2.2 Device Attributes
    #
    # To a device attributes can be added, they will automatically be
    # mirrored to the related context entity.
    # Each attribute needs a unique name.
Exemple #20
0
    zone_temperature_sensor = ...

    # ToDo: Get the service group configurations from the server
    group = iotac.get_group(resource="/iot/json", apikey=...)

    # ToDo: Create and additional device holding a command attribute and
    #  post it to the IoT-Agent. It should be mapped to the `type` heater
    # create the simtime attribute and add during device creation
    t_sim = DeviceAttribute(name='simtime', object_id='t_sim', type="Number")

    # ToDo: create the command attribute of name `heater_on` (currently it is
    #  not possible to add metadata here)
    cmd = DeviceCommand(name=..., type=...)

    # ToDo: create the device configuration and send it to the server name it
    heater = Device(...)

    iotac.post_device(device=heater)

    # ToDo: Check the entity that corresponds to your device
    heater_entity = cbc.get_entity(entity_id=heater.entity_name,
                                   entity_type=heater.entity_type)
    print(f"Your device entity before running the simulation: \n "
          f"{heater_entity.json(indent=2)}")

    # create a MQTTv5 client with paho-mqtt and the known groups and devices.
    mqttc = IoTAMQTTClient(
        protocol=mqtt.MQTTv5,
        devices=[weather_station, zone_temperature_sensor, heater],
        service_groups=[group])
    # set user data if required