Beispiel #1
0
// Decode decodes the payload using the Decoder function into a map
func (f *UplinkFunctions) Decode(payload []byte, port uint8) (map[string]interface{}, error) {
	if f.Decoder == "" {
		return nil, errors.NewErrInternal("Decoder function not set")
	}

	env := map[string]interface{}{
		"payload": payload,
		"port":    port,
	}
	code := fmt.Sprintf(`
		%s;
		Decoder(payload.slice(0), port);
	`, f.Decoder)

	value, err := functions.RunCode("decoder", code, env, timeOut, f.Logger)
	if err != nil {
		return nil, err
	}

	if !value.IsObject() {
		return nil, errors.NewErrInvalidArgument("Decoder", "does not return an object")
	}

	v, _ := value.Export()
	m, ok := v.(map[string]interface{})
	if !ok {
		return nil, errors.NewErrInvalidArgument("Decoder", "does not return an object")
	}
	return m, nil
}
Beispiel #2
0
// Validate validates the values in the specified map using the Validator
// function. If the Validator function is not set, this function returns true
func (f *UplinkFunctions) Validate(fields map[string]interface{}, port uint8) (bool, error) {
	if f.Validator == "" {
		return true, nil
	}

	env := map[string]interface{}{
		"fields": fields,
		"port":   port,
	}
	code := fmt.Sprintf(`
		%s;
		Validator(fields, port)
	`, f.Validator)

	value, err := functions.RunCode("valdator", code, env, timeOut, f.Logger)
	if err != nil {
		return false, err
	}

	if !value.IsBoolean() {
		return false, errors.NewErrInvalidArgument("Validator", "does not return a boolean")
	}

	return value.ToBoolean()
}
Beispiel #3
0
// Convert converts the values in the specified map to a another map using the
// Converter function. If the Converter function is not set, this function
// returns the data as-is
func (f *UplinkFunctions) Convert(fields map[string]interface{}, port uint8) (map[string]interface{}, error) {
	if f.Converter == "" {
		return fields, nil
	}

	env := map[string]interface{}{
		"fields": fields,
		"port":   port,
	}

	code := fmt.Sprintf(`
		%s;
		Converter(fields, port)
	`, f.Converter)

	value, err := functions.RunCode("converter", code, env, timeOut, f.Logger)
	if err != nil {
		return nil, err
	}

	if !value.IsObject() {
		return nil, errors.NewErrInvalidArgument("Converter", "does not return an object")
	}

	v, _ := value.Export()
	m, ok := v.(map[string]interface{})
	if !ok {
		return nil, errors.NewErrInvalidArgument("Converter", "does not return an object")
	}

	return m, nil
}
Beispiel #4
0
// Encode encodes the map into a byte slice using the encoder payload function
// If no encoder function is set, this function returns an array.
func (f *DownlinkFunctions) Encode(payload map[string]interface{}, port uint8) ([]byte, error) {
	if f.Encoder == "" {
		return nil, errors.NewErrInvalidArgument("Downlink Payload", "fields supplied, but no Encoder function set")
	}

	env := map[string]interface{}{
		"payload": payload,
		"port":    port,
	}
	code := fmt.Sprintf(`
		%s;
		Encoder(payload, port)
	`, f.Encoder)

	value, err := functions.RunCode("encoder", code, env, timeOut, f.Logger)
	if err != nil {
		return nil, err
	}

	if !value.IsObject() {
		return nil, errors.NewErrInvalidArgument("Encoder", "does not return an object")
	}

	v, err := value.Export()
	if err != nil {
		return nil, err
	}

	if reflect.TypeOf(v).Kind() != reflect.Slice {
		return nil, errors.NewErrInvalidArgument("Encoder", "does not return an Array")
	}

	s := reflect.ValueOf(v)
	l := s.Len()

	res := make([]byte, l)

	var n int64
	for i := 0; i < l; i++ {
		el := s.Index(i).Interface()

		// type switch does not have fallthrough so we need
		// to check every element individually
		switch t := el.(type) {
		case byte:
			n = int64(t)
		case int:
			n = int64(t)
		case int8:
			n = int64(t)
		case int16:
			n = int64(t)
		case uint16:
			n = int64(t)
		case int32:
			n = int64(t)
		case uint32:
			n = int64(t)
		case int64:
			n = int64(t)
		case uint64:
			n = int64(t)
		case float32:
			n = int64(t)
			if float32(n) != t {
				return nil, errors.NewErrInvalidArgument("Encoder", "should return an Array of integer numbers")
			}
		case float64:
			n = int64(t)
			if float64(n) != t {
				return nil, errors.NewErrInvalidArgument("Encoder", "should return an Array of integer numbers")
			}
		default:
			return nil, errors.NewErrInvalidArgument("Encoder", "should return an Array of integer numbers")
		}

		if n < 0 || n > 255 {
			return nil, errors.NewErrInvalidArgument("Encoder Output", "Numbers in Array should be between 0 and 255")
		}

		res[i] = byte(n)
	}

	return res, nil
}