Beispiel #1
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)
Beispiel #2
0
                     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.
    #
    # ### 2.2.1 StaticDeviceAttribute
    #
    # These attributes represent static information (as names) and are
    # mirrored 1:1
    device2.add_attribute(
        StaticDeviceAttribute(name="address",
                              type=DataType.TEXT,
                              value="Lichtenhof 3"))
    # ### 2.2.2 DeviceAttribute
    #
    # These attributes represent a live information of the device.
    # The value can be read by accessing the mirrored attribute in the
    # context entity.
    # It is differentiated between two kinds:
    #
    # DeviceAttributes, always keep the value in the context entity up-to-date
    # (polling)
    device2.add_attribute(DeviceAttribute(name="temperature", object_id="t"))
    # LazyDeviceAttributes, only update the value in the entity if it is
    # accessed (event based)
    device2.add_attribute(LazyDeviceAttribute(name="temperature"))
    # information about units.
    device_attr1 = DeviceAttribute(name='temperature',
                                   object_id='t',
                                   type="Number",
                                   metadata={
                                       "unit": {
                                           "type": "Unit",
                                           "value": {
                                               "name": "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')

    # 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],
Beispiel #4
0
    #  attribute to the weather station

    # create the context attribute for the building and add it to the
    # building entity
    has_weather_station = NamedContextAttribute(
        name="hasWeatherStation",
        type="Relationship",
        value=weather_station.entity_name)
    building.add_attributes(attrs=[has_weather_station])

    # create a static attribute that connects the weather station to the
    # building
    cbc.update_entity(entity=building)

    ref_building = StaticDeviceAttribute(name="refBuilding",
                                         type="Relationship",
                                         value=building.id)
    weather_station.add_attribute(ref_building)
    iotac.update_device(device=weather_station)

    # ToDo: Semantically connect the zone temperature sensor and the thermal
    #  zone by adding a `hasTemperatureSensor` attribute of type
    #  `Relationship` to the thermal zone entity.
    #  For the connection from the sensor to the zone add a static
    #  attribute to the temperature sensor device

    # ToDo: create the context attribute for the thermal zone and add it to the
    #   thermal zone entity
    has_sensor = ...

    thermal_zone.add_attributes(...)
Beispiel #5
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()
Beispiel #6
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()
Beispiel #7
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()