Beispiel #1
0
        /// <summary>
        /// Add time-series data to the channel.
        /// </summary>
        /// <param name="sensorName">sensor containing the channel to add data to.</param>
        /// <param name="channelName">channel to add data to.</param>
        /// <param name="sampleRate">sample-rate for points in data</param>
        /// <param name="data">a list of points to add to the channel.
        /// <remarks>The points should be ordered and match the sample-rate provided.</remarks>
        /// </param>
        public void AddTimeSeriesData(SampleRate sampleRate, IEnumerable <Point> data)
        {
            var payload = new MemoryStream();
            var xdr     = new XdrWriter(payload);

            const int VERSION = 1;

            xdr.WriteInt(VERSION);
            xdr.WriteInt(sampleRate.Type.ToXdr());
            xdr.WriteInt(sampleRate.Rate);

            //Writing an array in XDR.  an array is always prefixed by the array length
            xdr.WriteInt(data.Count());
            foreach (Point p in data)
            {
                xdr.WriteUnsingedHyper(p.UnixTimestamp);
                xdr.WriteFloat(p.Value);
            }

            string url     = "/sensors/" + _sensorName + "/channels/" + this.Name + "/streams/timeseries/data/";
            var    request = _requests.url(url)
                             .Param("version", "1")
                             .ContentType("application/xdr")
                             .Data(payload.ToArray())
                             .Put();

            // check the response code for success
            if (request.ResponseCode != HttpStatusCode.Created)
            {
                throw SensorCloudException.GenerateSensorCloudException(request, "AddTimeSeriesData failed.");
            }
        }
Beispiel #2
0
        /// <summary>
        /// Add a new sensor to the Device.
        /// </summary>
        /// <param name="sensorName">Name that will be given to the sensor.  Once a sensor is created it's name cannot be changed.
        /// <remarks>sensorName must be between 1 and 50 characters in length, and only contain characters in the set[A-Z,a-z,0-9,_]</remarks>
        /// </param>
        /// <param name="label">User Friendly label for the sensor.  May be changed later.
        /// <remarks>label supports unicode, and must not be more than 50 bytes when encoded as UTF-8.</remarks>
        /// </param>
        /// <param name="type">Type of the sensor. May be changed later.
        /// <remarks>type supports unicode, and must not be more than 50 bytes when encoded as UTF-8.</remarks>
        /// </param>
        /// <param name="description">Description of the sensor.  May be changed later.
        /// <remarks>description supports unicode, and must not be more than 1000 bytes when encoded as UTF-8.</remarks>
        /// </param>
        public Sensor AddSensor(String sensorName, String label, String type, String description)
        {
            var payload = new MemoryStream();
            var xdr     = new XdrWriter(payload);

            int VERSION = 1;

            xdr.WriteInt(VERSION);
            xdr.WriteString(type);
            xdr.WriteString(label);
            xdr.WriteString(description);

            var request = _requests.url("/sensors/" + sensorName + "/")
                          .Param("version", "1")
                          .ContentType("application/xdr")
                          .Data(payload.ToArray())
                          .Put();

            // check the response code for success
            if (request.ResponseCode != HttpStatusCode.Created)
            {
                throw SensorCloudException.GenerateSensorCloudException(request, "AddSensor Failed");
            }

            return(new Sensor(sensorName, _requests));
        }
Beispiel #3
0
        // Save  type, label, and descritpion to SensorCloud
        private void  SaveState(string label, string description, string type)
        {
            var payload = new MemoryStream();
            var xdr     = new XdrWriter(payload);

            const int VERSION = 1;

            xdr.WriteInt(VERSION);
            xdr.WriteString(type);
            xdr.WriteString(label);
            xdr.WriteString(description);


            var request = _requests.url("/sensors/" + this.Name + "/")
                          .Param("version", "1")
                          .Accept("application/xdr")
                          .ContentType("application/xdr")
                          .Data(payload.ToArray())
                          .Post();

            if (request.ResponseCode != HttpStatusCode.Created)
            {
                throw SensorCloudException.GenerateSensorCloudException(request, "Save Sensor state failed.");
            }
        }
Beispiel #4
0
        private IList <Point> DownloadData(ulong startTime, ulong endTime)
        {
            //url: /sensors/<sensor_name>/channels/<channel_name>/streams/timeseries/data/
            // params:
            //    starttime (required)
            //    endtime  (required)
            //    showSampleRateBoundary (oiptional)
            //    samplerate (oiptional)

            string url     = "/sensors/" + _sensorName + "/channels/" + this._channelName + "/streams/timeseries/data/";
            var    request = _requests.url(url)
                             .Param("version", "1")
                             .Param("starttime", startTime)
                             .Param("endtime", endTime)
                             .Accept("application/xdr")
                             .Get();

            // check the response code for success
            if (request.ResponseCode == HttpStatusCode.NotFound)
            {
                //404 is an empty list
                return(new List <Point>());
            }
            else if (request.ResponseCode != HttpStatusCode.OK)
            {
                //all other errors are exceptions
                throw SensorCloudException.GenerateSensorCloudException(request, "AddTimeSeriesData failed.");
            }

            var xdrReader = new XdrReader(request.Raw);

            var datapoints = new List <Point>();

            ulong timestamp;
            float value;

            try
            {
                // timeseries/data always returns a relativly small chunk of data less than 50,000 points so we can proccess it all at once.  We won't be given an infinite stream
                //however a futre enhancemnts could be to stat proccessing this stream as soon as we have any bytes avialable to the user, so they could be
                //iterating over the data while it is still being downloaded.
                while (true)
                {
                    timestamp = xdrReader.ReadUnsingedHyper();
                    value     = xdrReader.ReadFloat();

                    datapoints.Add(new Point(timestamp, value));
                }
            }
            catch (EndOfStreamException)
            {}

            return(datapoints);
        }
Beispiel #5
0
        /// <summary>
        /// Delete a channel from the Sensor.  Deleteing a channel will delete all the data that is assosiated with the channel.
        /// </summary>
        /// <param name="channelName"></param>
        public void DeleteChannel(string channelName)
        {
            var request = _requests.url("/sensors/" + this.Name + "/channels/" + channelName + "/")
                          .Param("version", "1")
                          .Delete();

            if (request.ResponseCode != HttpStatusCode.NoContent)
            {
                throw SensorCloudException.GenerateSensorCloudException(request, "Delete channel Failed");
            }
        }
Beispiel #6
0
        /// <summary>
        /// Determine if a sensor exists for this Device.
        /// </summary>
        /// <param name="sensorName"></param>
        /// <returns>True if the sensor exists.</returns>
        public bool HasSensor(String sensorName)
        {
            var request = _requests.url("/sensors/" + sensorName + "/")
                          .Param("version", "1")
                          .Accept("application/xdr")
                          .Get();

            // check the response code for success
            switch (request.ResponseCode)
            {
            case HttpStatusCode.OK: return(true);

            case HttpStatusCode.NotFound: return(false);

            default: throw SensorCloudException.GenerateSensorCloudException(request, "HasSensor failed");
            }
        }
Beispiel #7
0
        /// <summary>
        /// Determine if a channel for a specific sensor exits for the Device.
        /// </summary>
        /// <param name="sensorName"></param>
        /// <param name="channelName"></param>
        /// <returns>True if the channel exists</returns>
        /// <exception cref="SensorCloudException">Unexpected response from server.</exception>
        public bool HasChannel(string channelName)
        {
            //make a get request for channel attributes to determine if the channel exists
            String url     = "/sensors/" + this.Name + "/channels/" + channelName + "/attributes/";
            var    request = _requests.url(url)
                             .Param("version", "1")
                             .Accept("application/xdr")
                             .Get();

            // check the response code for success
            switch (request.ResponseCode)
            {
            case HttpStatusCode.OK: return(true);

            case HttpStatusCode.NotFound: return(false);

            default: throw SensorCloudException.GenerateSensorCloudException(request, "Unexpected response for HasChannel.");
            }
        }
Beispiel #8
0
        /// <summary>
        /// Load info about this sensor from SensorCloud
        /// If this sensor doesn't exist then an exception will be thrown
        /// </summary>
        private void LoadFromSensorCloud()
        {
            if (_infoLoaded)
            {
                return;
            }

            //make a get request for channel attributes to determine if the channel exists
            var request = _requests.url("/sensors/" + this.Name + "/")
                          .Param("version", "1")
                          .Accept("application/xdr")
                          .Get();

            // check the response code for success
            if (request.ResponseCode == HttpStatusCode.OK)
            {
                var ms      = new MemoryStream(request.Raw);
                var xdr     = new XdrReader(ms);
                int version = xdr.ReadInt();
                if (version != 1)
                {
                    throw new SensorCloudException("Unsupported xdr version");
                }

                string type        = xdr.ReadString(1000);
                string label       = xdr.ReadString(1000);            //a token is generally about 60 chars.  Limit the read to at most 1000 chars as a precation so in their is a protocol error we don't try to allocate lots of memory
                string descripiton = xdr.ReadString(1000);


                //Only if we get all the fields from xdr do we update this instance.  This prevents us from paritally updating the state of the instance.
                _label       = label;
                _description = descripiton;
                _sensorType  = type;
            }
            else
            {
                throw SensorCloudException.GenerateSensorCloudException(request, "Get Sensor Failed");
            }

            _infoLoaded = true;
        }
Beispiel #9
0
        /// <summary>
        /// Get a list of existing Sensors for this device.
        /// </summary>
        public List <Sensor> GetSensors()
        {
            List <Sensor> outputList = new List <Sensor>();
            //make a get request for channel attributes to determine if the channel exists
            var request = _requests.url("/sensors/")
                          .Param("version", "1")
                          .Accept("application/xdr")
                          .Get();

            // check the response code for success
            if (request.ResponseCode == HttpStatusCode.OK)
            {
                var ms  = new MemoryStream(request.Raw);
                var xdr = new XdrReader(ms);
                //The first value is the version.  We expect this to be 1
                int version = xdr.ReadInt();
                if (version != 1)
                {
                    throw new SensorCloudException("Unsupported xdr version");
                }

                //The next value is an integer telling us how many sensors to unpack
                //Each sensor has its info packed a certain way, so this allows us to know how many sensors we must unpack
                int sensorCount = xdr.ReadInt();
                //loop through sensors
                for (var i = 0; i < sensorCount; i++)
                {
                    string sensorName = xdr.ReadString(1000);
                    //for example's sake, I'm going to push a Sensor Object onto our output array
                    //This object only needs the Sensor name, and will fetch the Sensor info on it's own
                    //However, to get all sensor names we must still parse all of the stream.  You can modify
                    //this function to meet your own needs, and return a different set of information
                    //tailored to what you need.
                    outputList.Add(new Sensor(sensorName, _requests));

                    string sensortype        = xdr.ReadString(1000);
                    string sensorlabel       = xdr.ReadString(1000);                //a token is generally about 60 chars.  Limit the read to at most 1000 chars as a precation so in their is a protocol error we don't try to allocate lots of memory
                    string sensordescripiton = xdr.ReadString(1000);

                    //the next value is the number of channels this sensor has
                    int channelCount = xdr.ReadInt();
                    //loop all channels
                    for (var j = 0; j < channelCount; j++)
                    {
                        string channelName        = xdr.ReadString(1000);
                        string channelLabel       = xdr.ReadString(1000);
                        string channelDescription = xdr.ReadString(1000);

                        //This tells us how many datastreams the channel has
                        //This should be one, as we only currently support TimeSeries, but could grow as more stream types are added
                        int streamCount = xdr.ReadInt();
                        //loop through streams
                        for (var k = 0; k < streamCount; k++)
                        {
                            //the first value in the stream is the type of stream.  We expect this to be TS_V1, meaning timeseries version 1
                            string streamType = xdr.ReadString(1000);
                            //the second value of a stream is the number of bytes that describes the stream.
                            //This is convenient as it allows us to just skip the stream if we are not interested in it.
                            //For this example's purpose, we are uninterested and will simply skip ahead in the xdr.  We do this by reading the number bytes, but doing anything
                            //with the data
                            int totalBytes = xdr.ReadInt();
                            //just reading the bytes by previously parsed length advances the xdr reader forward in the data
                            xdr.ReadBytes(totalBytes);
                        }
                    }
                }
                return(outputList);
            }
            else
            {
                throw SensorCloudException.GenerateSensorCloudException(request, "Get Sensors Failed");
            }
        }