Exemple #1
0
        /// <summary>
        /// Creates a new HomieColor from an RGB string.
        /// </summary>
        public static HomieColor FromRgbString(string rgbString)
        {
            HomieColor returnColor;

            if (ValidatePayload(rgbString, ColorFormat.Rgb))
            {
                returnColor = new HomieColor();

                var colorParts = rgbString.Split(',');

                returnColor.RedValue   = int.Parse(colorParts[0]);
                returnColor.GreenValue = int.Parse(colorParts[1]);
                returnColor.BlueValue  = int.Parse(colorParts[2]);
            }
            else
            {
                returnColor = new HomieColor();
            }

            return(returnColor);
        }
Exemple #2
0
        private void SetValue(HomieColor valueToSet)
        {
            switch (Type)
            {
            case PropertyType.Parameter:
            case PropertyType.Command:
                if (_colorFormat == ColorFormat.Rgb)
                {
                    _rawValue = valueToSet.ToRgbString();
                }
                else
                {
                    _rawValue = valueToSet.ToHsvString();
                }

                _parentDevice.InternalPropertyPublish($"{_propertyId}/set", _rawValue, false);
                break;

            case PropertyType.State:
                throw new InvalidOperationException();
            }
        }
Exemple #3
0
        protected override bool ValidatePayload(string payloadToValidate)
        {
            var areNumbersGood = HomieColor.ValidatePayload(payloadToValidate, _colorFormat);

            return(areNumbersGood);
        }
Exemple #4
0
        /// <summary>
        /// Creates a new HomieColor from an HSV string.
        /// </summary>
        public static HomieColor FromHsvString(string hsvString)
        {
            HomieColor returnColor;

            if (ValidatePayload(hsvString, ColorFormat.Hsv))
            {
                returnColor = new HomieColor();

                var colorParts = hsvString.Split(',');

                var hue        = int.Parse(colorParts[0]);
                var saturation = int.Parse(colorParts[1]) / 100.0;
                var value      = int.Parse(colorParts[2]) / 100.0;

                // Took conversion from Wikipedia https://en.wikipedia.org/wiki/HSL_and_HSV
                var chroma = saturation * value;
                var hPrime = hue / 60.0;
                var x      = chroma * (1 - Math.Abs(hPrime % 2 - 1));

                var redPrime   = 0.0;
                var greenPrime = 0.0;
                var bluePrime  = 0.0;
                if (hPrime <= 1)
                {
                    redPrime   = chroma;
                    greenPrime = x;
                    bluePrime  = 0;
                }
                else if (hPrime <= 2)
                {
                    redPrime   = x;
                    greenPrime = chroma;
                    bluePrime  = 0;
                }
                else if (hPrime <= 3)
                {
                    redPrime   = 0;
                    greenPrime = chroma;
                    bluePrime  = x;
                }
                else if (hPrime <= 4)
                {
                    redPrime   = 0;
                    greenPrime = x;
                    bluePrime  = chroma;
                }
                else if (hPrime <= 5)
                {
                    redPrime   = x;
                    greenPrime = 0;
                    bluePrime  = chroma;
                }
                else if (hPrime <= 6)
                {
                    redPrime   = chroma;
                    greenPrime = 0;
                    bluePrime  = x;
                }

                var m = value - chroma;

                returnColor.RedValue   = (redPrime + m) * 255;
                returnColor.GreenValue = (greenPrime + m) * 255;
                returnColor.BlueValue  = (bluePrime + m) * 255;
            }
            else
            {
                returnColor = new HomieColor();
            }

            return(returnColor);
        }
        public bool ValidateAndFix(ref ArrayList errorList, ref ArrayList warningList)
        {
            var isOk = true;

            if ((PropertyType == PropertyType.Command) && (InitialValue != ""))
            {
                warningList.Add($"{NodeId}/{PropertyId} property type is Command, but it has initial value set. Clearing it.");

                InitialValue = "";
            }

            var isNotCommand = PropertyType != PropertyType.Command;

            switch (DataType)
            {
            case DataType.String:
                // String type has pretty much no restriction to attributes content.
                break;

            case DataType.Integer:
            case DataType.Float:
                // Trying to convert integer to float. Later, float validation will simply run on this converted property.
                if (DataType == DataType.Integer)
                {
                    if (isNotCommand && (Helpers.IsInteger(InitialValue) == false))
                    {
                        errorList.Add($"{NodeId}/{PropertyId} is set to {InitialValue}, which is not a valid initial value for integer data type. Skipping this property entirely.");
                        isOk = false;
                    }

                    if (isOk)
                    {
                        warningList.Add($"{NodeId}/{PropertyId} is originally of type integer, but it will now be converted to float.");

                        Tags.Add("Precision", "0");
                        DataType = DataType.Float;
                    }
                }

                if (isNotCommand && (Helpers.IsFloat(InitialValue) == false))
                {
                    errorList.Add($"{NodeId}/{PropertyId} is set to {InitialValue}, which is not a valid initial value for float data type. Skipping this property entirely.");
                    isOk = false;
                }
                break;

            case DataType.Boolean:
            case DataType.Enum:
                // Trying to convert boolean type to enum. Later, enum validation will simply run on this converted property.
                if (DataType == DataType.Boolean)
                {
                    if (isNotCommand && (Helpers.TryParseBool(InitialValue, out _) == false))
                    {
                        errorList.Add($"{NodeId}/{PropertyId} is set to {InitialValue}, which is not a valid initial value for boolean data type. Skipping this property entirely.");
                        isOk = false;
                    }

                    if (isOk)
                    {
                        warningList.Add($"{NodeId}/{PropertyId} is originally of type boolean, but it will now be converted to enum.");

                        Format   = "false,true";
                        DataType = DataType.Enum;

                        if (Unit != "")
                        {
                            warningList.Add($"{NodeId}/{PropertyId}/$unit attribute is {Unit}. Should be empty for boolean data type. Clearing it.");
                            Unit = "";
                        }
                    }
                }

                // From here, the save procedure will run on both enum and (former) boolean properties.
                if (Format == "")
                {
                    errorList.Add($"{NodeId}/{PropertyId}/$format attribute is empty, which is not valid for enum data type. Skipping this property entirely.");
                    isOk = false;
                }

                var options = Format.Split(',');

                if (isOk)
                {
                    if (options.Length < 2)
                    {
                        errorList.Add($"{NodeId}/{PropertyId}/$format attribute contains less than two option. Skipping this property entirely.");
                        isOk = false;
                    }
                }

                if (isOk)
                {
                    var isInitialValueCorrect = false;
                    foreach (var option in options)
                    {
                        if (InitialValue == option)
                        {
                            isInitialValueCorrect = true;
                        }
                    }

                    if (isNotCommand && (isInitialValueCorrect == false))
                    {
                        errorList.Add($"{NodeId}/{PropertyId} is set to {InitialValue}, while it should be one of {Format}. Skipping this property entirely.");
                        isOk = false;
                    }
                }
                break;

            case DataType.Color:
                if (Format == "")
                {
                    errorList.Add($"{NodeId}/{PropertyId}/$format attribute is empty, which is not valid for color data type. Skipping this property entirely.");
                    isOk = false;
                }

                if (isOk)
                {
                    if (Helpers.TryParseHomieColorFormat(Format, out var colorFormat) == false)
                    {
                        errorList.Add($"{NodeId}/{PropertyId}/$format attribute is {Format}, which is not valid for color data type. Skipping this property entirely.");
                        isOk = false;
                    }
                    else if (isNotCommand)
                    {
                        if (HomieColor.ValidatePayload(InitialValue, colorFormat) == false)
                        {
                            errorList.Add($"{NodeId}/{PropertyId} is set to {InitialValue}, which is not valid for color format {colorFormat}. Skipping this property entirely.");
                            isOk = false;
                        }
                    }
                }
                break;

            case DataType.DateTime:
                if (isNotCommand && (Helpers.TryParseDateTime(InitialValue, out var _) == false))
                {
                    errorList.Add($"{NodeId}/{PropertyId} is set to {InitialValue}, which is not a valid initial value for datetime data type. Skipping this property entirely.");
                    isOk = false;
                }
                if (Unit != "")
                {
                    warningList.Add($"{NodeId}/{PropertyId}/$unit attribute is {Unit}. Should be empty for datetime data type. Clearing it.");
                    Unit = "";
                }
                if (Format != "")
                {
                    warningList.Add($"{NodeId}/{PropertyId}/$format attribute is {Unit}. Should be empty for datetime data type. Clearing it.");
                    Format = "";
                }
                break;

            case DataType.Duration:
                errorList.Add($"{NodeId}/{PropertyId} is of type {DataType}, but this is not currently supported by YAHI. Skipping this property entirely.");
                isOk = false;
                break;
            }

            return(isOk);
        }