def lambda_handler()

in transform_binary_payload/src-iotrule-transformation/app.py [0:0]


def lambda_handler(event, context):
    """ Transforms a binary payload by invoking "decode_{event.type}" function
        Parameters 
        ----------
        PayloadData : str (obligatory parameter)
            Base64 encoded input payload

        PayloadDecoderName : string (obligatory parameter)
            The value of this attribute defines the name of a Python module which will be used to perform binary decoding. If value of "type" is for example "sample_device", then this function will perform an invocation of "sample_device.dict_from_payload" function. For this approach to work, you  have to import the necessary modules, e.g. by performing a "import sample_device01" command in the beginning of this file.

        WirelessDeviceId : str (optional parameter)
            Wireless Device Id

        WirelessMetadata : json (obligatory parameter)
            This parameter contains Metadata of transmission according to the example below.
            Obligatory element is: LoRaWAN.FPort
            All other elements are optional and ignored in the current implementation.

            Sample input:
            {
            "LoRaWAN": {
                "DataRate": 0,
                "DevEui": "a84041d55182720b",
                "FPort": 21,
                "Frequency": 867900000,
                "Gateways": [
                {
                    "GatewayEui": "dca632fffe45b3c0",
                    "Rssi": -76,
                    "Snr": 9.75
                }
                ],
                "Timestamp": "2020-12-07T14:41:48Z"
            }

        Returns
        -------
        This function returns a JSON object with the following keys:

        - status: 200 or 500
        - transformed_payload: output of function "decode_{event.type}"     (only if status == 200)
        - error_type                                                        (only if status == 500)
        - error_message                                                     (only if status == 500)
        - stackTrace                                                        (only if status == 500)


    """
    logger.info("Received event: %s" % json.dumps(event))

    # Store event input and perform input validation
    input_base64 = event.get("PayloadData")
    payload_decoder_name = event.get("PayloadDecoderName")

    # Validate existence of payload type
    if payload_decoder_name is None:
        raise InvalidInputException(
            "PayloadDecoderName is not specified")

    # Validate  if payload type is in the list of allowed values
    if payload_decoder_name not in VALID_PAYLOAD_DECODER_NAMES:
        raise InvalidInputException(
            "PayloadDecoderName have one of the following values:"+(".".join(VALID_PAYLOAD_DECODER_NAMES)))

    logger.info(f"Base64 input={input_base64}, Type={payload_decoder_name}")

    # Retrieve FPort from the metadata. In case FPort or surrounding attributes is missing,
    # the function will intentionally not fail but proceed with fPort == None.
    # The binary decoder function is expected to handle fPort == None.
    fPort = None
    if "WirelessMetadata" in event:
        if "LoRaWAN" in event.get("WirelessMetadata"):
            if "FPort" in event.get("WirelessMetadata").get("LoRaWAN"):
                fPort = event.get("WirelessMetadata").get(
                    "LoRaWAN").get("FPort")
            else:
                logger.warn(
                    "Attribute 'WirelessMetadata.LoRaWAN' is missing. Will proceed with fPort == None.")
        else:
            logger.warn(
                "Attribute 'WirelessMetadata.LoRaWAN' is missing. Will proceed with fPort == None.")
    else:
        logger.warn(
            "Attribute 'WirelessMetadata' is missing. Will proceed with fPort == None.")

    # Derive a name of a payload conversion function based on the value of 'type' attribute
    conversion_function_name = f"{payload_decoder_name}.dict_from_payload"
    logger.info(f"Function name={conversion_function_name}")

    # Invoke a payload conversion function and return a result
    try:
        result = eval(conversion_function_name)(input_base64, fPort)
        result["status"] = 200
        result["decoder_name"] = payload_decoder_name
        logger.info(result)
        return result

    except Exception as exp:
        exception_type, exception_value, exception_traceback = sys.exc_info()
        traceback_string = traceback.format_exception(
            exception_type, exception_value, exception_traceback)
        result = {
            "status": 500,
            "decoder_name": payload_decoder_name,
            "errorType": exception_type.__name__,
            "errorMessage": str(exception_value),
            "stackTrace": traceback_string
        }
        logger.error(result)
        return result