/// <summary>
        /// Parse Http response string and return a ThingSpeakHttpResponse object
        /// </summary>
        /// <param name="response">Http response string</param>
        /// <returns>ThingSpeakHttpResponse object</returns>
        internal static ThingSpeakHttpResponse Parse(string response)
        {
            ThingSpeakHttpResponse httpResponse = new ThingSpeakHttpResponse();
            int i = 0;
            int headerSize = 0;

            // split response lines on line feed
            string[] lines = response.Split(LF);
            // trim line on carriage return
            lines[i] = lines[i].TrimEnd(CR);

            // headers end with empty string
            while (lines[i] != String.Empty)
            {
                // calculate header size
                headerSize += lines[i].Length + CRLF.Length;

                int separatorIndex = lines[i].IndexOf(":");

                // first line contains Http response code
                if (i == 0)
                {
                    httpResponse.ResponseCode = lines[i];
                    httpResponse.StatusCode = Convert.ToInt32(httpResponse.ResponseCode.Substring(httpResponse.ResponseCode.IndexOf(' ') + 1, 3));
                }
                // found header-value separator
                else if (separatorIndex != -1)
                    httpResponse.Headers.Add(lines[i].Substring(0, separatorIndex), lines[i].Substring(separatorIndex + 1).Trim());

                i++;
                // trim end carriage return of each line
                lines[i] = lines[i].TrimEnd(CR);
            }

            // next line (body start)
            i++;

            // set start of body inside response
            int bodyOffset = headerSize + CRLF.Length;
            // get body from entire response
            string body = response.Substring(bodyOffset);

            // content length specified
            if (httpResponse.Headers.Contains("Content-Length"))
            {
                httpResponse.Body = body.Substring(0, Convert.ToInt32(httpResponse.Headers["Content-Length"].ToString()));
            }
            // transfer encoding specified
            else if (httpResponse.Headers.Contains("Transfer-Encoding"))
            {
                // body chunked
                if (httpResponse.Headers["Transfer-Encoding"].ToString() == "chunked")
                {
                    httpResponse.Body = String.Empty;
                    int chunkDim = 0;
                    int currBodyOffset = 0;
                    do
                    {
                        // get chunk dimension
                        chunkDim = Convert.ToInt32(body.Substring(0, body.IndexOf(CRLF)), 16);
                        // get the following body chunk
                        if (chunkDim != 0)
                        {
                            // set offset after chunk dimension
                            currBodyOffset = body.IndexOf(CRLF) + CRLF.Length;
                            // get the body chunk
                            httpResponse.Body += body.Substring(currBodyOffset, chunkDim);
                            // update body part to analize
                            body = body.Substring(currBodyOffset + chunkDim + CRLF.Length);
                        }
                    } while (chunkDim != 0);
                    // trim last CRLF of body
                    httpResponse.Body = httpResponse.Body.TrimEnd(LF).TrimEnd(CR);
                }
            }

            return httpResponse;
        }
Esempio n. 2
0
        /// <summary>
        /// Update a channel
        /// </summary>
        /// <param name="writeApiKey">Write API Key for the channel to update</param>
        /// <param name="dataEntry">Data entry for updating channel</param>
        /// <returns>Update result</returns>
        public bool Update(
            string writeApiKey,
            DataEntry dataEntry)
        {
            // check for a mandatory write API Key
            if ((writeApiKey == null) || (writeApiKey == String.Empty))
            {
                throw new ArgumentNullException("writeApiKey", "You must specify a write API Key");
            }

            // check max fields number
            if (dataEntry.Fields.Length > THING_SPEAK_MAX_FIELDS)
            {
                throw new ArgumentException("fields", "Max number of field is " + THING_SPEAK_MAX_FIELDS);
            }

            // check at leaset one field value not empty
            bool checkFields = false;

            for (int i = 0; i < dataEntry.Fields.Length; i++)
            {
                if (dataEntry.Fields[i] != null)
                {
                    checkFields = true;
                    break;
                }
            }
            if (!checkFields)
            {
                throw new ArgumentNullException("fields", "You must specify a field value at least");
            }

            // check status message
            if ((dataEntry.Status != null) && (dataEntry.Status.Length > THING_SPEAK_MAX_STATUS))
            {
                throw new ArgumentException("status", "Max status length is " + THING_SPEAK_MAX_STATUS);
            }

            // check twitter account and message
            if (((dataEntry.Twitter == null) && (dataEntry.Tweet != null)) || ((dataEntry.Twitter != null) && (dataEntry.Tweet == null)))
            {
                throw new ArgumentException("twitter and tweet parameters must be both valued");
            }

            // build body
            string body = String.Empty;

            // fields...
            for (int i = 0; i < dataEntry.Fields.Length; i++)
            {
                if ((dataEntry.Fields[i] != null) && (dataEntry.Fields[i] != String.Empty))
                {
                    if (i > 0)
                    {
                        body += "&";
                    }
                    body += "field" + (i + 1) + "=" + dataEntry.Fields[i];
                }
            }
            // ...location...
            if (dataEntry.Location != null)
            {
                body += "&lat=" + dataEntry.Location.Latitude + "&long=" + dataEntry.Location.Longitude + "&elevation=" + dataEntry.Location.Elevation;
            }
            // ...status...
            if (dataEntry.Status != null)
            {
                body += "&status=" + dataEntry.Status;
            }
            // ...twitter...
            if ((dataEntry.Twitter != null) && (dataEntry.Tweet != null))
            {
                body += "&twitter=" + dataEntry.Twitter + "&tweet=" + dataEntry.Tweet;
            }

            // build HTTP request
            string request = "POST " + THING_SPEAK_UPDATE_PATH + " HTTP/1.1" + CRLF;

            request += "Host: " + THING_SPEAK_HOST + CRLF;
            request += "Connection: close" + CRLF;
            request += "X-THINGSPEAKAPIKEY: " + writeApiKey + CRLF;
            request += "Content-Type: application/x-www-form-urlencoded" + CRLF;
            request += "Content-Length: " + body.Length + CRLF;
            request += CRLF;
            request += body + CRLF;

            string result = String.Empty;

            // open socket e connect to the host
            using (this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                this.socket.Connect(this.hostIpEndPoint);

                // send HTTP request
                this.sendBuffer = Encoding.UTF8.GetBytes(request);

                if (this.SSL)
                {
                    // TODO : HTTPS communication
                }
                else
                {
                    // send HTTP request
                    this.socket.Send(this.sendBuffer);

                    // receive HTTP response
                    this.receiveBuffer = new byte[RECEIVE_BUFFER_SIZE];

                    // poll on socket for reading (timeout 30 sec)
                    while (this.socket.Poll(30 * 1000000, SelectMode.SelectRead))
                    {
                        // no data on th socket (closed or timeout)
                        if (this.socket.Available == 0)
                        {
                            break;
                        }

                        // empty buffer
                        Array.Clear(this.receiveBuffer, 0, this.receiveBuffer.Length);

                        // read data
                        this.socket.Receive(this.receiveBuffer);

                        // append response
                        result += new String(Encoding.UTF8.GetChars(this.receiveBuffer));
                    }
                }
            }

            // decode HTTP response
            ThingSpeakHttpResponse httpResponse = ThingSpeakHttpResponse.Parse(result);

            Debug.Print(result);

            if (httpResponse.StatusCode == 200)
            {
                // set entry Id received from the server
                dataEntry.Id = Convert.ToInt32(httpResponse.Body);
                return(true);
            }
            else
            {
                return(false);
            }
        }
        /// <summary>
        /// Parse Http response string and return a ThingSpeakHttpResponse object
        /// </summary>
        /// <param name="response">Http response string</param>
        /// <returns>ThingSpeakHttpResponse object</returns>
        internal static ThingSpeakHttpResponse Parse(string response)
        {
            ThingSpeakHttpResponse httpResponse = new ThingSpeakHttpResponse();
            int i          = 0;
            int headerSize = 0;

            // split response lines on line feed
            string[] lines = response.Split(LF);
            // trim line on carriage return
            lines[i] = lines[i].TrimEnd(CR);

            // headers end with empty string
            while (lines[i] != String.Empty)
            {
                // calculate header size
                headerSize += lines[i].Length + CRLF.Length;

                int separatorIndex = lines[i].IndexOf(":");

                // first line contains Http response code
                if (i == 0)
                {
                    httpResponse.ResponseCode = lines[i];
                    httpResponse.StatusCode   = Convert.ToInt32(httpResponse.ResponseCode.Substring(httpResponse.ResponseCode.IndexOf(' ') + 1, 3));
                }
                // found header-value separator
                else if (separatorIndex != -1)
                {
                    httpResponse.Headers.Add(lines[i].Substring(0, separatorIndex), lines[i].Substring(separatorIndex + 1).Trim());
                }

                i++;
                // trim end carriage return of each line
                lines[i] = lines[i].TrimEnd(CR);
            }

            // next line (body start)
            i++;

            // set start of body inside response
            int bodyOffset = headerSize + CRLF.Length;
            // get body from entire response
            string body = response.Substring(bodyOffset);

            // content length specified
            if (httpResponse.Headers.Contains("Content-Length"))
            {
                httpResponse.Body = body.Substring(0, Convert.ToInt32(httpResponse.Headers["Content-Length"].ToString()));
            }
            // transfer encoding specified
            else if (httpResponse.Headers.Contains("Transfer-Encoding"))
            {
                // body chunked
                if (httpResponse.Headers["Transfer-Encoding"].ToString() == "chunked")
                {
                    httpResponse.Body = String.Empty;
                    int chunkDim       = 0;
                    int currBodyOffset = 0;
                    do
                    {
                        // get chunk dimension
                        chunkDim = Convert.ToInt32(body.Substring(0, body.IndexOf(CRLF)), 16);
                        // get the following body chunk
                        if (chunkDim != 0)
                        {
                            // set offset after chunk dimension
                            currBodyOffset = body.IndexOf(CRLF) + CRLF.Length;
                            // get the body chunk
                            httpResponse.Body += body.Substring(currBodyOffset, chunkDim);
                            // update body part to analize
                            body = body.Substring(currBodyOffset + chunkDim + CRLF.Length);
                        }
                    } while (chunkDim != 0);
                    // trim last CRLF of body
                    httpResponse.Body = httpResponse.Body.TrimEnd(LF).TrimEnd(CR);
                }
            }

            return(httpResponse);
        }
Esempio n. 4
0
        /// <summary>
        /// Read channel data entries
        /// </summary>
        /// <param name="readApiKey">Read API Key for the channel to read (null if channel is public)</param>
        /// <param name="channelId">Channel ID</param>
        /// <param name="path">Path for reading channel</param>
        /// <returns>List of all data entries read</returns>
        private ArrayList ReadChannel(string readApiKey, int channelId, string path)
        {
            // build HTTP request
            string request = "GET /channels/" + channelId + path + " HTTP/1.1" + CRLF;

            request += "Host: " + THING_SPEAK_HOST + CRLF;
            request += "Connection: close" + CRLF;
            if ((readApiKey != null) && (readApiKey != String.Empty))
            {
                request += "X-THINGSPEAKAPIKEY: " + readApiKey + CRLF;
            }
            request += CRLF;

            string result = String.Empty;

            // open socket e connect to the host
            using (this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                this.socket.Connect(this.hostIpEndPoint);

                this.sendBuffer = Encoding.UTF8.GetBytes(request);

                if (this.SSL)
                {
                    // TODO : HTTPS communication
                }
                else
                {
                    // send HTTP request
                    this.socket.Send(this.sendBuffer);

                    // receive HTTP response
                    this.receiveBuffer = new byte[RECEIVE_BUFFER_SIZE];

                    // poll on socket for reading (timeout 30 sec)
                    while (this.socket.Poll(30 * 1000000, SelectMode.SelectRead))
                    {
                        // no data on th socket (closed or timeout)
                        if (this.socket.Available == 0)
                        {
                            break;
                        }

                        // empty buffer
                        Array.Clear(this.receiveBuffer, 0, this.receiveBuffer.Length);

                        // read data
                        this.socket.Receive(this.receiveBuffer);

                        // append response
                        result += new String(Encoding.UTF8.GetChars(this.receiveBuffer));
                    }
                }
            }

            // decode HTTP response
            ThingSpeakHttpResponse httpResponse = ThingSpeakHttpResponse.Parse(result);

            Debug.Print(result);

            if (httpResponse.StatusCode == 200)
            {
                return(DataEntry.ParseCsv(httpResponse.Body));
            }
            else
            {
                return(null);
            }
        }