예제 #1
0
    def post(self):
        """Method to create an application property"""
        appeui = self.args['appeui']
        port = self.args['port']
        name = self.args['name']
        type = self.args['type']

        message = {}
        # Check for required args
        required = {'appeui', 'port', 'name', 'type'}
        for r in required:
            if self.args[r] is None:
                message[r] = "Missing the {} parameter.".format(r)
        if message:
            abort(400, message=message)

        # Return a 404 if the application is not found.
        app = yield Application.find(where=['appeui = ?', appeui], limit=1)
        if app is None:
            abort(404,
                  message={
                      'error':
                      "Application {} doesn't exist.".format(euiString(appeui))
                  })

        # Check this property does not currently exist
        exists = yield AppProperty.exists(
            where=['application_id = ? AND port = ?', app.id, port])
        if exists:
            message = {
                'error':
                "Application property for appeui {}, port "
                "{} exists".format(euiString(appeui), port)
            }
            abort(400, message=message)

        # Create and validate
        p = AppProperty(application_id=app.id, port=port, name=name, type=type)

        (valid, message) = yield p.valid()
        if not valid:
            abort(400, message=message)

        try:
            prop = yield p.save()
            if prop is None:
                abort(500, message={'error': "Error saving the property."})
            location = self.restapi.api.prefix + '/property/' + str(prop.id)
            returnValue(({}, 201, {'Location': location}))

        except TimeoutError:
            log.error(
                "REST API timeout post application {appeui} "
                "property {port}",
                appeui=euiString(appeui),
                port=port)
예제 #2
0
    def get(self, appeui):
        """Method to handle application property GET requests
        
        Args:
            appeui (int): Application EUI
            port (int): Application property port
        """
        try:
            app = yield Application.find(where=['appeui = ?', appeui], limit=1)
            # Return a 404 if not found.
            if app is None:
                abort(404,
                      message={
                          'error':
                          "Application {} doesn't exist.".format(
                              euiString(appeui))
                      })

            port = self.args['port']
            p = yield AppProperty.find(
                where=['application_id = ? AND port = ?', app.id, port])
            if p is None:
                abort(404,
                      message={'error': "Application property doesn't exist."})

            data = marshal(p, self.fields)
            returnValue(data)

        except TimeoutError:
            log.error(
                "REST API timeout get request for application {appeui} "
                "property {port}",
                appeui=euiString(appeui),
                port=port)
예제 #3
0
    def _test_appproperty(self):
        """Create a test AppProperty object"""

        return AppProperty(
            application_id=1,
            port=15,
            name='Temperature',
            type='float',
        )
예제 #4
0
    def netServerReceived(self, device, app, port, appdata):
        """Receive application data from the network server
        
        We issue a POST request to the Azure IOT hub host with appdata
        as the data parameter.
        
        Args:
            device (Device): LoRa device object
            app (Application): device's application
            port (int): fport of the frame payload
            appdata (str): Application data
        """

        # Map the device name the Azure IOT deviceId
        devid = device.appname if device.appname else device.name

        prop = yield AppProperty.find(
            where=['application_id = ? and port = ?', app.id, port], limit=1)

        # If the property is not found, send the data as is.
        if prop is None:
            data = appdata
        else:
            # Create the Azure message. If not mapped, transparently send appdata
            data = self._azureMessage(devid, prop, appdata)
            if data is None:
                log.debug(
                    "Application interface {name} could not create "
                    "message for property {prop}",
                    name=self.name,
                    prop=prop.name)
                returnValue(None)

        # Form the URL, headers and parameters
        url = 'https://{}/devices/{}/messages/events'.format(
            self.iothost.lower(), devid.lower())
        resuri = '{}/devices/{}'.format(self.iothost, devid)
        headers = {'Authorization': self._iotHubSasToken(resuri)}
        params = {'api-version': self.API_VERSION}

        # Issue the POST request
        try:
            r = requests.post(url,
                              headers=headers,
                              params=params,
                              data=data,
                              timeout=self.TIMEOUT)
        except requests.exceptions.RequestException:
            log.debug(
                "Application interface {name} could not send to "
                "Azure IOT Hub {host} for device ID {device}",
                name=self.name,
                host=self.iothost,
                device=devid)
예제 #5
0
    def netServerReceived(self, device, app, port, appdata):
        """Receive application data from the network server
        
        We publish outbound appdata to the Azure IOT hub host, and
        receive inbound messages, via MQTT.
        
        Args:
            device (Device): LoRa device object
            app (Application): device's application
            port (int): fport of the frame payload
            appdata (str): Application data
        """
        if not self.started:
            returnValue(None)

        # Map the device name the Azure IOT deviceId
        devid = device.appname if device.appname else device.name

        prop = yield AppProperty.find(
            where=['application_id = ? and port = ?', app.id, port], limit=1)

        # If the property is not found, send the data as is.
        if prop is None:
            data = appdata
        else:
            # Create the Azure message. If not mapped, transparently send appdata
            data = self._azureMessage(devid, prop, appdata)
            if data is None:
                log.debug(
                    "Application interface {name} could not create "
                    "message for property {prop}",
                    name=self.name,
                    prop=prop.name)
                returnValue(None)

        resuri = '{}/devices/{}'.format("fluentiothub.azure-devices.net",
                                        devid)
        username = '******'.format(
            devid, self.API_VERSION)
        password = self._iotHubSasToken(resuri)

        service = MQTTService(self.endpoint, self.factory, devid, username,
                              password)
        messages = yield service.publishMessage(appdata)

        for m in messages:
            self.netserver.netServerReceived(device.devaddr, m)
예제 #6
0
    def put(self, appeui):
        """Method to handle application property PUT requests
        
        Args:
            appeui (int): Application EUI
        """
        try:
            app = yield Application.find(where=['appeui = ?', appeui], limit=1)
            # Return a 404 if not found.
            if app is None:
                abort(404,
                      message={
                          'error':
                          "Application {} doesn't exist.".format(
                              euiString(appeui))
                      })
            port = self.args['port']

            p = yield AppProperty.find(
                where=['application_id = ? AND port = ?', app.id, port],
                limit=1)
            if p is None:
                abort(404,
                      message={'error': "Application property doesn't exist."})

            kwargs = {}
            for a, v in self.args.items():
                if a not in {'name', 'type', 'port'}:
                    continue
                if v is not None and v != getattr(p, a):
                    kwargs[a] = v
                    setattr(p, a, v)
            (valid, message) = yield p.valid()
            if not valid:
                abort(400, message=message)

            # Update the model
            if kwargs:
                p.update(**kwargs)
            returnValue(({}, 200))

        except TimeoutError:
            log.error(
                "REST API timeout put request for application {appeui} "
                "property {port}",
                appeui=euiString(appeui),
                port=port)
예제 #7
0
    def delete(self, appeui):
        """Method to handle application property DELETE requests
        
        Args:
            appeui (int): application EUI
        """

        try:
            # Return a 404 if the application is not found.
            app = yield Application.find(where=['appeui = ?', appeui], limit=1)
            if app is None:
                abort(404,
                      message={
                          'error':
                          "Application {} doesn't exist.".format(
                              euiString(appeui))
                      })
            port = self.args['port']

            # Return a 404 if the property is not found.
            p = yield AppProperty.find(
                where=['application_id = ? AND port = ?', app.id, port],
                limit=1)
            if p is None:
                abort(404,
                      message={'error': "Application property doesn't exist."})

            yield p.delete()
            returnValue(({}, 200))

        except TimeoutError:
            log.error(
                "REST API timeout retrieving application {appeui} "
                "property {port}",
                appeui=euiString(appeui),
                port=port)