public static MeasuredValue ConvertTo(string name, DateTime timeStamp, string valueAsText, TypeCode targetType)
        {
            MeasuredValue mv           = new MeasuredValue();
            bool          convertState = false;

            mv.Name      = name;
            mv.TimeStamp = timeStamp;
            switch (targetType)
            {
            case TypeCode.Boolean:
                bool boolvalue = false;
                convertState = bool.TryParse(valueAsText, out boolvalue);
                mv.Value     = boolvalue;
                break;

            case TypeCode.Int16:
                Int16 i16value = 0;
                convertState = Int16.TryParse(valueAsText, out i16value);
                mv.Value     = i16value;
                break;

            case TypeCode.Int32:
                Int32 i32value = 0;
                convertState = Int32.TryParse(valueAsText, out i32value);
                mv.Value     = i32value;
                break;

            case TypeCode.Int64:
                Int64 i64value = 0;
                convertState = Int64.TryParse(valueAsText, UsedNumberStyle, UsedCultureInfo, out i64value);
                mv.Value     = i64value;
                break;

            case TypeCode.Single:
                float fvalue = 0;
                convertState = float.TryParse(valueAsText, UsedNumberStyle, UsedCultureInfo, out fvalue);
                mv.Value     = fvalue;
                break;

            case TypeCode.Double:
                double dvalue = 0;
                convertState = double.TryParse(valueAsText, UsedNumberStyle, UsedCultureInfo, out dvalue);
                mv.Value     = dvalue;
                break;

            case TypeCode.String:
                convertState = string.IsNullOrEmpty(valueAsText) == false;
                mv.Value     = valueAsText;
                break;

            default:
                throw new Exception("type currently not supported: " + targetType.ToString());
            }
            if (false == convertState)
            {
                mv.Quality = OPCQuality.NoValue;
            }
            return(mv);
        }
        /// <summary>
        /// Check all conditions and decide if the current should be written
        /// </summary>
        /// <param name="currentValue">the current measured value</param>
        /// <param name="previousValue">the previous measured value </param>
        /// <returns></returns>
        public bool ShouldCurrentValueBeWritten(MeasuredValue currentValue, MeasuredValue previousValue)
        {
            if (currentValue == null)
            {
                throw new ArgumentNullException("currentValue");
            }
            if (previousValue == null)
            {
                throw new ArgumentNullException("previousValue");
            }

            _logger.DebugFormat("Previous value: {0}", previousValue.ToString());
            _logger.DebugFormat("Current value:  {0}", currentValue.ToString());

            // OPCQuality.NoValue means that no value is available
            // OPCQuality.NoValue should never be written to the database
            // if current value is "NoValue" => don't write value
            if (currentValue.Quality == OPCQuality.NoValue)
            {
                _logger.Debug("don't write value: OPCQuality = NoValue");
                return(false);
            }

            // if the quality of the previous value was "NoValue"
            // then write the current, because this is the first value ever
            if (previousValue.Quality == OPCQuality.NoValue)
            {
                _logger.InfoFormat("write value (no previous value): {0}", currentValue.ToString());
                return(true);
            }

            // both must be true to write value
            if (CheckConditionTimeDeadBandIsMet(currentValue, previousValue))
            {
                if (CheckConditionValueDeadBandDeltaIsMet(currentValue, previousValue))
                {
                    _logger.InfoFormat("write value: Current: {0} / Previous {1}", currentValue.ToString(), previousValue.ToString());
                    return(true);
                }
            }

            // if all the conditions above are not meet, check if it is time to write a value
            // but then set the current time to the current value
            if (CheckConditionRewriteValueAfterIsMet(currentValue, previousValue))
            {
                currentValue.TimeStamp = DateTime.Now;
                _logger.InfoFormat("write value (rewrite after): Current: {0} / Previous {1}", currentValue.ToString(), previousValue.ToString());
                return(true);
            }
            return(false);
        }
        /// <summary>
        /// Check if the condition "ValueDeadBandDelta" is met
        /// Condition: The absolute difference between
        /// the currrent and the previous value is bigger than
        /// ValueDeadBandDelta
        /// </summary>
        /// <param name="currentValue">the current measured value</param>
        /// <param name="previousValue">the previous measured value </param>
        /// <returns></returns>
        public bool CheckConditionValueDeadBandDeltaIsMet(MeasuredValue currentValue, MeasuredValue previousValue)
        {
            if (currentValue == null)
            {
                throw new ArgumentNullException("currentValue");
            }
            if (previousValue == null)
            {
                throw new ArgumentNullException("previousValue");
            }
            if (ValueDeadBandDelta == 0)
            {
                _logger.DebugFormat("ValueDeadBandPercentIsMet: ValueDeadBandPercent = {0}", ValueDeadBandDelta);
                return(true);
            }
            bool equal = currentValue.Value.ToString() == previousValue.Value.ToString();

            if (equal)
            {
                return(false);
            }
            double result = 0;
            double value1 = 0;
            double value2 = 0;

            switch (currentValue.GetTypeCode())
            {
            case TypeCode.Double:
                value1 = (double)previousValue.Value;
                value2 = (double)currentValue.Value;
                break;

            case TypeCode.Int32:
                value1 = Convert.ToDouble((int)previousValue.Value);
                value2 = Convert.ToDouble((int)currentValue.Value);
                break;

            default:
                return(true);
            }
            if (value1 > value2)
            {
                result = value2;
                value2 = value1;
                value1 = result;
            }
            result = Math.Abs(value2 - value1);
            _logger.DebugFormat("ValueDeadBandDeltaIsMet: {0} Result: {1} %: {2}", result > ValueDeadBandDelta, result, ValueDeadBandDelta);
            return(result > ValueDeadBandDelta);
        }
        /// <summary>
        /// Check if the condition "TimeDeadBand" is met
        /// Condition: The previous value was written before
        /// "now" - TimeDeadBand
        /// </summary>
        /// <param name="currentValue">the current measured value</param>
        /// <param name="previousValue">the previous measured value </param>
        /// <returns></returns>
        public bool CheckConditionTimeDeadBandIsMet(MeasuredValue currentValue, MeasuredValue previousValue)
        {
            if (currentValue == null)
            {
                throw new ArgumentNullException("currentValue");
            }
            if (previousValue == null)
            {
                throw new ArgumentNullException("previousValue");
            }
            TimeSpan sp = currentValue.TimeStamp - previousValue.TimeStamp;

            if (sp.TotalSeconds > TimeDeadBand.TotalSeconds)
            {
                _logger.DebugFormat("TimeDeadBandIsMet: {0} > {1}", sp.TotalSeconds, TimeDeadBand.TotalSeconds);
                return(true);
            }
            return(false);
        }
        /// <summary>
        /// Check if the condition "RewriteValueAfter" is met
        /// Condition: The previous value was written earlier than
        /// "now" - RewriteValue
        /// </summary>
        /// <param name="currentValue">the current measured value</param>
        /// <param name="previousValue">the previous measured value </param>
        /// <returns></returns>
        public bool CheckConditionRewriteValueAfterIsMet(MeasuredValue currentValue, MeasuredValue previousValue)
        {
            if (currentValue == null)
            {
                throw new ArgumentNullException("currentValue");
            }
            if (previousValue == null)
            {
                throw new ArgumentNullException("previousValue");
            }

            TimeSpan sp = currentValue.TimeStamp - previousValue.TimeStamp;

            if (RewriteValueAfter.TotalSeconds < sp.TotalSeconds)
            {
                _logger.DebugFormat("RewriteValueAfterIsMet: {0} < {1}", RewriteValueAfter.TotalSeconds, sp.TotalSeconds);
                return(true);
            }
            return(false);
        }