Channel data seems to be reported via the Rest API (sometimes) via exponential notation like this: -000000000000062-0.1000. Most programming languages expect something like -000000000000062E-0.1000 or even better -62E-0.1. I'm using C# w/ JSON.NET serialization.

Tried changing the channel data to 2 decimal points in settings but no effect on query via API, I imagine that just affects the graph representation.

Is there any way to control this? I'm using content=sensors and content=channels calls, looking at the _RAW data.

Thanks

ps - the captcha is impossible and really is it necessary when one has logged in?


Article Comments

Dear Lisa

I am sorry, we need the captcha to prevent the KB being flooded by spam.

The data returned by the API has to be converted within your script. The API only provides the raw data without the option to set a numerical format.


Aug, 2014 - Permalink

I've looked at this further - its apparently a formatting bug not an odd exponential notation. I think this : -000000000000062-0.1000 is meant to represent -62.1.

Could someone at PRTG confirm this and give me an actual characterization of the bug so that I know how to compensate for it? I'm seeing it only on raw channel data, not on the primary data for a sensor, but I don't know if that's a data-dependent coincidence.

Also, its unclear to me in what situations the divisor is or is not applied to raw data - both channel data and sensor primary data.

Lisa


Aug, 2014 - Permalink

Dear Lisa

Please send the API call you use and the output file you get to support@paessler.com so that we can inspect what exactly is going on.


Aug, 2014 - Permalink

Paessler support has answered this question for me. Here's response in case it helps someone else: " The data format you see is an internal format. For some sensors, PRTG automatically converts the internal format to a readable one.

In the case when this internal format is not converted but shown as-is, for example "-000000000000031-0.1000" please manually cut the "-0." part out and replace it with a point. For nonnegative numbers, like "0000000000000000.0000", cut "0." out and replace it with a decimal point as well. "

I'm using JSON.NET serialization on a WCF REST service API, so my workaround is to apply this converter to the sensor channel raw data property. NOTE - my channel data is negative, so if you use this solution please double-check the positive data translation.

    /// <summary>
    /// Sensor channel data from request : 
    /// </summary>
    [DataContract]
    public class SensorChannelData
    {
        [DataMember(Name = "channels")]
        public ChannelData[] ChannelData { get; private set; }
    }

    [DataContract]
    public class ChannelData
    {
        [DataMember(Name = "name")]
        public ChannelType ChannelType { get; private set; }
        [DataMember(Name = "lastvalue")]
        public string DataString { get; private set; }
        [DataMember(Name = "lastvalue_raw")]
        [JsonConverter(typeof(PrtgRawDataJsonConverter))]
        public decimal ? Data { get; private set; }
    }

    /// <summary>
    /// PRTG raw data has an occasional formatting problem in channel raw data.
    /// This converter detects and modifies to a standard format
    /// </summary>
    /// <remarks>Annotate any PRTG channel raw data value property with this converter.</remarks>
    internal class PrtgRawDataJsonConverter :JsonConverter
    {
        private static readonly Regex NegativeMatch = new Regex(@"-(?:0|[1-9]\d*)(-0\.\d+)");
        private static readonly Regex PositiveMatch = new Regex(@"(0\d*)(0\.\d+)");
        /// <summary>
        /// Default implementation
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="value"></param>
        /// <param name="serializer"></param>
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            serializer.Serialize(writer, value);
        }

        /// <summary>
        /// Deserialize property value from PRTG formatted number string.
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="objectType"></param>
        /// <param name="existingValue"></param>
        /// <param name="serializer"></param>
        /// <returns></returns>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.None) return null;

            if (reader.TokenType == JsonToken.None) return null;
            var x = reader.Value as string;
            if (!string.IsNullOrEmpty(x))
            {
                // match number format like -00000000000000014-0.5 which translates apparently to -14.5
                if (NegativeMatch.IsMatch(x))
                {
                    x = x.Remove(x.LastIndexOf("-0.", StringComparison.InvariantCultureIgnoreCase), 2);
                }
                // match number format like 000000000000000140.5 which translates apparently to 14.5
                else if (PositiveMatch.IsMatch(x))
                {
                    x = x.Remove(x.LastIndexOf("0.", StringComparison.InvariantCultureIgnoreCase), 1);
                }
                try
                {
                    return JsonConvert.DeserializeObject(x, objectType);
                }
                catch (Exception ex)
                {
                    ex.LogAsIgnored();
                }
                return null;
            }
            // default number parsing
            return serializer.Deserialize(reader, objectType);
        }

        /// <summary>
        /// Can convert any number ( value type assignable from int)
        /// </summary>
        /// <param name="objectType"></param>
        /// <returns></returns>
        public override bool CanConvert(Type objectType)
        {
            return objectType.IsValueType && objectType.IsAssignableFrom(typeof (int));
        }
    }

Aug, 2014 - Permalink