/// <summary>
        /// Returns a full-size or scaled image given its URI. Input parameters include resolution. This is the only command that should return
        /// </summary>
        /// <param name="fileUri">URI of the target file. Manufacturers decide whether to use absolute or relative URIs. Clients may treat this as an opaque identifier.</param>
        /// <param name="type">enum DataType { full, thumb }</param>
        /// <param name="callback">Action&lt;byte[], Error&gt;</param>
        public void GetImage(string fileUri, DataType type, Action<byte[], Error> callback)
        {
            CommandRequest request = new CommandRequest("camera.getImage");

            request.AddParameter("fileUri", fileUri);

            request.AddParameter("_type", type.ToString());

            CommandExecute(request, (response) =>
            {
                callback(response.bytes, response.error);
            });
        }
        /// <summary>
        /// Turn off the wireless LAN
        /// </summary>
        /// <param name="callback">Action&lt;Error&gt;</param>
        public void FinishWlan(Action<Error> callback)
        {
            CommandRequest request = new CommandRequest("camera._finishWlan");

            request.AddParameter("sessionId", currentSessionId);

            CommandExecute(request, (response) =>
            {
                callback(response.error);
            });
        }
        /// <summary>
        /// Retrieve live preview bynary data. The data format is &quot;Equirectangular&quot; and &quot;MotionJPEG&quot;.
        /// </summary>
        public void GetLivePreview(Action<byte[], Error> callback)
        {
            CommandRequest request = new CommandRequest("camera._getLivePreview");

            request.AddParameter("sessionId", currentSessionId);

            CommandExecute(request, (response) =>
            {
                callback(response.bytes, response.error);
            });
        }
        /// <summary>
        /// Start the interval still image capturing or video recording.
        /// Capture mode is selected by captureMode of Option.
        /// </summary>
        /// <param name="callback">Action&lt;Error&gt;</param>
        public void StartCapture(Action<Error> callback)
        {
            CommandRequest request = new CommandRequest("camera._startCapture");

            request.AddParameter("sessionId", currentSessionId);

            CommandExecute(request, (response) =>
            {
                callback(response.error);
            });
        }
        /// <summary>
        /// List all images
        /// </summary>
        /// <param name="entryCount">The list of entrys that vender specific of theta.</param>
        /// <param name="continuationToken"> (Optional) An opaque continuation token of type string, returned by previous listImages call, used to retrieve next images. </param>
        /// <param name="detail"></param>
        /// <param name="sort">sort string should be &quot;newest&quot; or &quot;oldest&quot;</param>
        /// <param name="callback">delegate void OnCompleteListAll(List&lt;ThetaEntry&gt; entries, int totalEntries, string continuationToken, Error error)</param>        
        public void ListAll(int entryCount, string continuationToken, bool detail, string sort, OnCompleteListAll callback)
        {
            CommandRequest request = new CommandRequest("camera._listAll");

            request.AddParameter("entryCount", entryCount);

            if(!string.IsNullOrEmpty(continuationToken))
                request.AddParameter("continuationToken", continuationToken);

            if(!detail)
                request.AddParameter("detail", detail);

            if (sort == "oldest")
                request.AddParameter("sort", sort);

            CommandExecute(request, (response) =>
            {
                if (response.error != null)
                {
                    callback(new List<ThetaEntry>(), 0, "", response.error);
                }
                else
                {
                    try
                    {
                        var entries = new List<ThetaEntry>();

                        if (response.results.Contains("entries"))
                        {
                            var list = (IList)response.results["entries"];

                            foreach (IDictionary dict in list)
                            {
                                var entry = new ThetaEntry();

                                JSONUtil.DictionaryToObjectFiled(dict, entry);

                                entries.Add(entry);
                            }
                        }

                        int _totalEntries = (response.results.Contains("totalEntries")) ? (int)((long)response.results["totalEntries"]) : 0;

                        string _continuationToken = (response.results.Contains("continuationToken")) ? (string)response.results["continuationToken"] : null;

                        callback(entries, _totalEntries, _continuationToken, null);

                    }
                    catch (System.Exception ex)
                    {
                        Error error = new Error();

                        error.message = ex.Message;

                        callback(new List<ThetaEntry>(), 0, null, response.error);
                    }
                }
            });
        }