// Get the whole REST API string for a device, from cache if possible
        internal virtual async Task <YJSONObject> requestAPI()
        {
            if (_cache_expiration > YAPI.GetTickCount())
            {
                return(_cache_json);
            }

            string request;

            if (_cache_json == null)
            {
                request = "GET /api.json \r\n\r\n";
            }
            else
            {
                string fw = _cache_json.getYJSONObject("module").getString("firmwareRelease");
                request = "GET /api.json?fw=" + YAPIContext.imm_escapeAttr(fw) + " \r\n\r\n";
            }

            string yreq = await requestHTTPSyncAsString(request, null);

            YJSONObject cache_json;

            try {
                cache_json = new YJSONObject(yreq);
                cache_json.parseWithRef(_cache_json);
            } catch (Exception ex) {
                _cache_json = null;
                throw new YAPI_Exception(YAPI.IO_ERROR, "Request failed, could not parse API (" + ex.Message + ")");
            }

            this._cache_expiration = YAPI.GetTickCount() + YAPI.DefaultCacheValidity;
            this._cache_json       = cache_json;
            return(cache_json);
        }