Example #1
0
void BootConfig::_onCaptivePortal() {
  String host = _http.hostHeader();
  if (host && !host.equalsIgnoreCase(F("homie.config"))) {
    // redirect unknown host requests to self if not connected to Internet yet
    if (!_proxyEnabled) {
      _interface->logger->logln(F("Received captive portal request"));
      // Catch any captive portal probe.
      // Every browser brand uses a different URL for this purpose
      // We MUST redirect all them to local webserver to prevent cache poisoning
      _http.sendHeader(F("Location"), F("http://homie.config/"));
      _http.send(302, F("text/plain"), F(""));
    // perform transparent proxy to Internet if connected
    } else {
      _proxyHttpRequest();
    }
  } else if (_http.uri() != "/" || !SPIFFS.exists(CONFIG_UI_BUNDLE_PATH)) {
    _interface->logger->logln(F("Received not found request"));
    _http.send(404, F("text/plain"), F("UI bundle not loaded. See Configuration API usage: http://marvinroger.viewdocs.io/homie-esp8266/6.-Configuration-API"));
  } else {
    _interface->logger->logln(F("Received UI request"));
    File file = SPIFFS.open(CONFIG_UI_BUNDLE_PATH, "r");
    _http.streamFile(file, F("text/html"));
    file.close();
  }
}
int32 TranslationManager::findMatchingLanguage(const String &lang) {
	uint langLength = lang.size();
	uint numLangs = _langs.size();

	// Try to match languages of the same length or longer ones
	// that can be cut at the length of the given one.
	for (uint i = 0; i < numLangs; ++i) {
		uint iLength = _langs[i].size();
		if (iLength >= langLength) {
			// Found a candidate; compare the full string by default.
			String cmpLang = _langs[i];

			if ((iLength > langLength) && (_langs[i][langLength] == '_')) {
				// It has a separation mark at the length of the
				// requested language, so we can cut it.
				cmpLang = String(_langs[i].c_str(), langLength);
			}
			if (lang.equalsIgnoreCase(cmpLang))
				return i;
		}
	}

	// Couldn't find a matching language.
	return -1;
}
Example #3
0
void ConfigFile::Section::removeKey(const String &key) {
	for (List<KeyValue>::iterator i = keys.begin(); i != keys.end(); ++i) {
		if (key.equalsIgnoreCase(i->key)) {
			keys.erase(i);
			return;
		}
	}
}
int TableDefinition::findColumnIndex(const String &columnName) const {
  for(size_t i = 0; i < m_columns.size(); i++) {
    if(columnName.equalsIgnoreCase(m_columns[i].m_name)) {
      return (int)i;
    }
  }
  return -1;
}
/**
 * adds Header to the request
 * @param name
 * @param value
 * @param first
 */
void HTTPClient::addHeader(const String& name, const String& value, bool first) {

    // not allow set of Header handled by code
    if(!name.equalsIgnoreCase("Connection") && !name.equalsIgnoreCase("User-Agent") && !name.equalsIgnoreCase("Host") && !(_base64Authorization.length() && name.equalsIgnoreCase("Authorization"))) {
        String headerLine = name;
        headerLine += ": ";
        headerLine += value;
        headerLine += "\r\n";

        if(first) {
            _Headers = headerLine + _Headers;
        } else {
            _Headers += headerLine;
        }
    }

}
Example #6
0
void ConfigFile::removeSection(const String &section) {
	assert(isValidName(section));
	for (List<Section>::iterator i = _sections.begin(); i != _sections.end(); ++i) {
		if (section.equalsIgnoreCase(i->name)) {
			_sections.erase(i);
			return;
		}
	}
}
Example #7
0
int HVAC::CmdIdx(String s, const char **pCmds )
{
  int iCmd;

  for(iCmd = 0; pCmds[iCmd]; iCmd++)
  {
    if( s.equalsIgnoreCase( String(pCmds[iCmd]) ) )
      break;
  }
  return iCmd;
}
Example #8
0
Platform parsePlatform(const String &str) {
	if (str.empty())
		return kPlatformUnknown;

	// Handle some special case separately, for compatibility with old config
	// files.
	if (str == "1")
		return kPlatformAmiga;
	else if (str == "2")
		return kPlatformAtariST;
	else if (str == "3")
		return kPlatformMacintosh;

	const PlatformDescription *l = g_platforms;
	for (; l->code; ++l) {
		if (str.equalsIgnoreCase(l->code) || str.equalsIgnoreCase(l->code2) || str.equalsIgnoreCase(l->abbrev))
			return l->id;
	}

	return kPlatformUnknown;
}
Example #9
0
void ConfigFile::Section::setKey(const String &key, const String &value) {
	for (List<KeyValue>::iterator i = keys.begin(); i != keys.end(); ++i) {
		if (key.equalsIgnoreCase(i->key)) {
			i->value = value;
			return;
		}
	}

	KeyValue newKV;
	newKV.key = key;
	newKV.value = value;
	keys.push_back(newKV);
}
bool ProcessorGraph::processorWithSameNameExists(const String& name)
{
    for (int i = 0; i < getNumNodes(); i++)
    {
        Node* node = getNode(i);

        if (name.equalsIgnoreCase(node->getProcessor()->getName()))
            return true;

    }

    return false;

}
static JucerDocument* createDocument (SourceCodeDocument* cpp)
{
    CodeDocument& codeDoc = cpp->getCodeDocument();

    ScopedPointer<XmlElement> xml (JucerDocument::pullMetaDataFromCppFile (codeDoc.getAllContent()));

    if (xml == nullptr || ! xml->hasTagName (JucerDocument::jucerCompXmlTag))
        return nullptr;

    const String docType (xml->getStringAttribute ("documentType"));

    ScopedPointer<JucerDocument> newDoc;

    if (docType.equalsIgnoreCase ("Button"))
        newDoc = new ButtonDocument (cpp);

    if (docType.equalsIgnoreCase ("Component") || docType.isEmpty())
        newDoc = new ComponentDocument (cpp);

    if (newDoc != nullptr && newDoc->reloadFromDocument())
        return newDoc.release();

    return nullptr;
}
Example #12
0
String XmlDocument::expandEntity (const String& ent)
{
    if (ent.equalsIgnoreCase ("amp"))   return String::charToString ('&');
    if (ent.equalsIgnoreCase ("quot"))  return String::charToString ('"');
    if (ent.equalsIgnoreCase ("apos"))  return String::charToString ('\'');
    if (ent.equalsIgnoreCase ("lt"))    return String::charToString ('<');
    if (ent.equalsIgnoreCase ("gt"))    return String::charToString ('>');

    if (ent[0] == '#')
    {
        const juce_wchar char1 = ent[1];

        if (char1 == 'x' || char1 == 'X')
            return String::charToString (static_cast <juce_wchar> (ent.substring (2).getHexValue32()));

        if (char1 >= '0' && char1 <= '9')
            return String::charToString (static_cast <juce_wchar> (ent.substring (1).getIntValue()));

        setLastError ("illegal escape sequence", false);
        return String::charToString ('&');
    }

    return expandExternalEntity (ent);
}
Example #13
0
String XmlDocument::getParameterEntity (const String& entity)
{
    for (int i = 0; i < tokenisedDTD.size(); ++i)
    {
        if (tokenisedDTD[i] == entity
                && tokenisedDTD [i - 1] == "%"
                && tokenisedDTD [i - 2].equalsIgnoreCase ("<!entity"))
        {
            const String ent (tokenisedDTD [i + 1].trimCharactersAtEnd (">"));

            if (ent.equalsIgnoreCase ("system"))
                return getFileContents (tokenisedDTD [i + 2].trimCharactersAtEnd (">"));

            return ent.trim().unquoted();
        }
    }

    return entity;
}
Example #14
0
String rdata(String cstr)
{
  readagain:
  if (dbg>0)
  {
    reply(cstr);
  }else{
    reply("?");
  }
  String cst = "";
  while(Serial.available()>0)
  {
    cst += byte(Serial.read());
  }
  if (cst.equalsIgnoreCase("!"))
  {
    sprintln("cmd = "+cmdlck);
    goto readagain;
  }
  return cst;
}
Example #15
0
bool ESP8266WebServer::_parseRequest(WiFiClient& client) {
  // Read the first line of HTTP request
  String req = client.readStringUntil('\r');
  client.readStringUntil('\n');
  //reset header value
  for (int i = 0; i < _headerKeysCount; ++i) {
    _currentHeaders[i].value =String();
   }

  // First line of HTTP request looks like "GET /path HTTP/1.1"
  // Retrieve the "/path" part by finding the spaces
  int addr_start = req.indexOf(' ');
  int addr_end = req.indexOf(' ', addr_start + 1);
  if (addr_start == -1 || addr_end == -1) {
#ifdef DEBUG_ESP_HTTP_SERVER
    DEBUG_OUTPUT.print("Invalid request: ");
    DEBUG_OUTPUT.println(req);
#endif
    return false;
  }

  String methodStr = req.substring(0, addr_start);
  String url = req.substring(addr_start + 1, addr_end);
  String versionEnd = req.substring(addr_end + 8);
  _currentVersion = atoi(versionEnd.c_str());
  String searchStr = "";
  int hasSearch = url.indexOf('?');
  if (hasSearch != -1){
    searchStr = url.substring(hasSearch + 1);
    url = url.substring(0, hasSearch);
  }
  _currentUri = url;
  _chunked = false;

  HTTPMethod method = HTTP_GET;
  if (methodStr == "POST") {
    method = HTTP_POST;
  } else if (methodStr == "DELETE") {
    method = HTTP_DELETE;
  } else if (methodStr == "OPTIONS") {
    method = HTTP_OPTIONS;
  } else if (methodStr == "PUT") {
    method = HTTP_PUT;
  } else if (methodStr == "PATCH") {
    method = HTTP_PATCH;
  }
  _currentMethod = method;

#ifdef DEBUG_ESP_HTTP_SERVER
  DEBUG_OUTPUT.print("method: ");
  DEBUG_OUTPUT.print(methodStr);
  DEBUG_OUTPUT.print(" url: ");
  DEBUG_OUTPUT.print(url);
  DEBUG_OUTPUT.print(" search: ");
  DEBUG_OUTPUT.println(searchStr);
#endif

  //attach handler
  RequestHandler* handler;
  for (handler = _firstHandler; handler; handler = handler->next()) {
    if (handler->canHandle(_currentMethod, _currentUri))
      break;
  }
  _currentHandler = handler;

  String formData;
  // below is needed only when POST type request
  if (method == HTTP_POST || method == HTTP_PUT || method == HTTP_PATCH || method == HTTP_DELETE){
    String boundaryStr;
    String headerName;
    String headerValue;
    bool isForm = false;
    bool isEncoded = false;
    uint32_t contentLength = 0;
    //parse headers
    while(1){
      req = client.readStringUntil('\r');
      client.readStringUntil('\n');
      if (req == "") break;//no moar headers
      int headerDiv = req.indexOf(':');
      if (headerDiv == -1){
        break;
      }
      headerName = req.substring(0, headerDiv);
      headerValue = req.substring(headerDiv + 1);
      headerValue.trim();
       _collectHeader(headerName.c_str(),headerValue.c_str());

      #ifdef DEBUG_ESP_HTTP_SERVER
      DEBUG_OUTPUT.print("headerName: ");
      DEBUG_OUTPUT.println(headerName);
      DEBUG_OUTPUT.print("headerValue: ");
      DEBUG_OUTPUT.println(headerValue);
      #endif

      if (headerName.equalsIgnoreCase("Content-Type")){
        if (headerValue.startsWith("text/plain")){
          isForm = false;
        } else if (headerValue.startsWith("application/x-www-form-urlencoded")){
          isForm = false;
          isEncoded = true;
        } else if (headerValue.startsWith("multipart/")){
          boundaryStr = headerValue.substring(headerValue.indexOf('=')+1);
          isForm = true;
        }
      } else if (headerName.equalsIgnoreCase("Content-Length")){
        contentLength = headerValue.toInt();
      } else if (headerName.equalsIgnoreCase("Host")){
        _hostHeader = headerValue;
      }
    }

    if (!isForm){
      size_t plainLength;
      char* plainBuf = readBytesWithTimeout(client, contentLength, plainLength, HTTP_MAX_POST_WAIT);
      if (plainLength < contentLength) {
      	free(plainBuf);
      	return false;
      }
      if (contentLength > 0) {
        if (searchStr != "") searchStr += '&';
        if(isEncoded){
          //url encoded form
          String decoded = urlDecode(plainBuf);
          size_t decodedLen = decoded.length();
          memcpy(plainBuf, decoded.c_str(), decodedLen);
          plainBuf[decodedLen] = 0;
          searchStr += plainBuf;
        }
        _parseArguments(searchStr);
        if(!isEncoded){
          //plain post json or other data
          RequestArgument& arg = _currentArgs[_currentArgCount++];
          arg.key = "plain";
          arg.value = String(plainBuf);
        }

  #ifdef DEBUG_ESP_HTTP_SERVER
        DEBUG_OUTPUT.print("Plain: ");
        DEBUG_OUTPUT.println(plainBuf);
  #endif
        free(plainBuf);
      }
    }

    if (isForm){
      _parseArguments(searchStr);
      if (!_parseForm(client, boundaryStr, contentLength)) {
        return false;
      }
    }
  } else {
    String headerName;
    String headerValue;
    //parse headers
    while(1){
      req = client.readStringUntil('\r');
      client.readStringUntil('\n');
      if (req == "") break;//no moar headers
      int headerDiv = req.indexOf(':');
      if (headerDiv == -1){
        break;
      }
      headerName = req.substring(0, headerDiv);
      headerValue = req.substring(headerDiv + 2);
      _collectHeader(headerName.c_str(),headerValue.c_str());

	  #ifdef DEBUG_ESP_HTTP_SERVER
	  DEBUG_OUTPUT.print("headerName: ");
	  DEBUG_OUTPUT.println(headerName);
	  DEBUG_OUTPUT.print("headerValue: ");
	  DEBUG_OUTPUT.println(headerValue);
	  #endif

	  if (headerName.equalsIgnoreCase("Host")){
        _hostHeader = headerValue;
      }
    }
    _parseArguments(searchStr);
  }
  client.flush();

#ifdef DEBUG_ESP_HTTP_SERVER
  DEBUG_OUTPUT.print("Request: ");
  DEBUG_OUTPUT.println(url);
  DEBUG_OUTPUT.print(" Arguments: ");
  DEBUG_OUTPUT.println(searchStr);
#endif

  return true;
}
/**
 * handle the WebSocket header reading
 * @param client WSclient_t *  ptr to the client struct
 */
void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {

    headerLine->trim(); // remove \r

    if(headerLine->length() > 0) {
        DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str());

        if(headerLine->startsWith("HTTP/1.")) {
            // "HTTP/1.1 101 Switching Protocols"
            client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt();
        } else if(headerLine->indexOf(':')) {
            String headerName = headerLine->substring(0, headerLine->indexOf(':'));
            String headerValue = headerLine->substring(headerLine->indexOf(':') + 2);

            if(headerName.equalsIgnoreCase("Connection")) {
                if(headerValue.equalsIgnoreCase("upgrade")) {
                    client->cIsUpgrade = true;
                }
            } else if(headerName.equalsIgnoreCase("Upgrade")) {
                if(headerValue.equalsIgnoreCase("websocket")) {
                    client->cIsWebsocket = true;
                }
            } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Accept")) {
                client->cAccept = headerValue;
                client->cAccept.trim(); // see rfc6455
            } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Protocol")) {
                client->cProtocol = headerValue;
            } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Extensions")) {
                client->cExtensions = headerValue;
            } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Version")) {
                client->cVersion = headerValue.toInt();
            }
        } else {
            DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str());
        }

        (*headerLine) = "";
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
        client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine)));
#endif

    } else {
        DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header read fin.\n");
        DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Client settings:\n");

        DEBUG_WEBSOCKETS("[WS-Client][handleHeader]  - cURL: %s\n", client->cUrl.c_str());
        DEBUG_WEBSOCKETS("[WS-Client][handleHeader]  - cKey: %s\n", client->cKey.c_str());

        DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Server header:\n");
        DEBUG_WEBSOCKETS("[WS-Client][handleHeader]  - cCode: %d\n", client->cCode);
        DEBUG_WEBSOCKETS("[WS-Client][handleHeader]  - cIsUpgrade: %d\n", client->cIsUpgrade);
        DEBUG_WEBSOCKETS("[WS-Client][handleHeader]  - cIsWebsocket: %d\n", client->cIsWebsocket);
        DEBUG_WEBSOCKETS("[WS-Client][handleHeader]  - cAccept: %s\n", client->cAccept.c_str());
        DEBUG_WEBSOCKETS("[WS-Client][handleHeader]  - cProtocol: %s\n", client->cProtocol.c_str());
        DEBUG_WEBSOCKETS("[WS-Client][handleHeader]  - cExtensions: %s\n", client->cExtensions.c_str());
        DEBUG_WEBSOCKETS("[WS-Client][handleHeader]  - cVersion: %d\n", client->cVersion);

        bool ok = (client->cIsUpgrade && client->cIsWebsocket);

        if(ok) {
            switch(client->cCode) {
                case 101:  ///< Switching Protocols

                    break;
                case 403: ///< Forbidden
                    // todo handle login
                default:   ///< Server dont unterstand requrst
                    ok = false;
                    DEBUG_WEBSOCKETS("[WS-Client][handleHeader] serverCode is not 101 (%d)\n", client->cCode);
                    clientDisconnect(client);
                    break;
            }
        }

        if(ok) {

            if(client->cAccept.length() == 0) {
                ok = false;
            } else {
                // generate Sec-WebSocket-Accept key for check
                String sKey = acceptKey(client->cKey);
                if(sKey != client->cAccept) {
                    DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Sec-WebSocket-Accept is wrong\n");
                    ok = false;
                }
            }
        }

        if(ok) {

            DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Websocket connection init done.\n");
            headerDone(client);


            runCbEvent(WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length());

        } else {
            DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n");
            client->tcp->write("This is a webSocket client!");
            clientDisconnect(client);
        }
    }
}
Example #17
0
bool HttpRequest::isWebSocket()
{
	String req = getHeader("Upgrade");
	return req.equalsIgnoreCase("websocket");
}
Example #18
0
bool HttpRequest::isAjax()
{
	String req = getHeader("HTTP_X_REQUESTED_WITH");
	return req.equalsIgnoreCase("xmlhttprequest");
}
/**
 * reads the response from the server
 * @return int http code
 */
int HTTPClient::handleHeaderResponse() {

    if(!connected()) {
        return HTTPC_ERROR_NOT_CONNECTED;
    }

    String transferEncoding;
    _returnCode = -1;
    _size = -1;
    _transferEncoding = HTTPC_TE_IDENTITY;
    unsigned long lastDataTime = millis();

    while(connected()) {
        size_t len = _tcp->available();        
        if(len > 0) {
            //Serial.printf("received: %d\n",len);
            String headerLine = _tcp->readStringUntil('\n');
            headerLine.trim(); // remove \r

            lastDataTime = millis();

            DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] RX: '%s'\n", headerLine.c_str());

            if(headerLine.startsWith("HTTP/1.")) {
                _returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt();
            }else if(headerLine.indexOf(':')) {
                String headerName = headerLine.substring(0, headerLine.indexOf(':'));
                String headerValue = headerLine.substring(headerLine.indexOf(':') + 2);   
                if(headerName.equalsIgnoreCase("Content-Length")) {
                    _size = headerValue.toInt();
                }

                if(headerName.equalsIgnoreCase("Connection")) {
                    _canReuse = headerValue.equalsIgnoreCase("keep-alive");
                }

                if(headerName.equalsIgnoreCase("Transfer-Encoding")) {
                    transferEncoding = headerValue;
                }

                if(_usingSession && headerName.equalsIgnoreCase("Set-Cookie")){
                    _cookie += headerValue.substring(0,headerValue.indexOf(';')+1) + " ";
                }

                for(size_t i = 0; i < _headerKeysCount; i++) {
                    if(_currentHeaders[i].key.equalsIgnoreCase(headerName)) {
                        _currentHeaders[i].value = headerValue;
                        break;
                    }
                }
            }

            if(headerLine == "") {
                DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] code: %d\n", _returnCode);

                if(_size > 0) {
                    DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] size: %d\n", _size);
                }

                if(transferEncoding.length() > 0) {
                    DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] Transfer-Encoding: %s\n", transferEncoding.c_str());
                    if(transferEncoding.equalsIgnoreCase("chunked")) {
                        _transferEncoding = HTTPC_TE_CHUNKED;
                    } else {
                        return HTTPC_ERROR_ENCODING;
                    }
                } else {
                    _transferEncoding = HTTPC_TE_IDENTITY;
                }

                if(_returnCode) {
                    return _returnCode;
                } else {
                    DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] Remote host is not an HTTP Server!");
                    return HTTPC_ERROR_NO_HTTP_SERVER;
                }
            }

        } else {
            if((millis() - lastDataTime) > _tcpTimeout) {
                return HTTPC_ERROR_READ_TIMEOUT;
            }
            delay(0);
        }
    }

    return HTTPC_ERROR_CONNECTION_LOST;
}
/**
 * phasing the url for all needed informations
 * @param url String
 * @param httpsFingerprint String
 */
void HTTPClient::begin(String url, String httpsFingerprint) {

    DEBUG_HTTPCLIENT("[HTTP-Client][begin] url: %s\n", url.c_str());

    _httpsFingerprint = httpsFingerprint;
    _returnCode = 0;
    _size = -1;

    _Headers = "";

    String protocol;
    // check for : (http: or https:
    int index = url.indexOf(':');
    //int index2;
    bool hasPort = false;
    if(index >= 0) {
        protocol = url.substring(0, index);
        url.remove(0, (index + 3)); // remove http:// or https://

        index = url.indexOf('/');
        String host = url.substring(0, index);
        url.remove(0, index); // remove host part

        // get Authorization
        index = host.indexOf('@');
        if(index >= 0) {
            // auth info
            String auth = host.substring(0, index);
            host.remove(0, index + 1); // remove auth part including @
            _base64Authorization = base64::encode(auth);
        }

        // get port
        index = host.indexOf(':');
        if(index >= 0) {
            _host = host.substring(0, index); // hostname
            host.remove(0, (index + 1)); // remove hostname + :
            _port = host.toInt(); // get port
            hasPort = true;
        } else {
            _host = host;
        }

        _url = url;

        if(protocol.equalsIgnoreCase("http")) {
            _https = false;
            if(!hasPort) {
                _port = 80;
            }
        } else if(protocol.equalsIgnoreCase("https")) {
            _https = true;
            if(!hasPort) {
                _port = 443;
            }
        } else {
            DEBUG_HTTPCLIENT("[HTTP-Client][begin] protocol: %s unknown?!\n", protocol.c_str());
            return;
        }

    }

    DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port: %d url: %s https: %d httpsFingerprint: %s\n", _host.c_str(), _port, _url.c_str(), _https, _httpsFingerprint.c_str());

}
Example #21
0
void RgbLed::_setBrightness(String data){
  if(data.equalsIgnoreCase(String("high")) || data.equalsIgnoreCase(String("h"))){
    _brightness = B_HIGH;
  }
  else if(data.equalsIgnoreCase(String("medium high")) || data.equalsIgnoreCase(String("mhigh")) || data.equalsIgnoreCase(String("mh"))){
    _brightness = B_MEDIUM_HIGH;
  }
  else if(data.equalsIgnoreCase(String("medium")) || data.equalsIgnoreCase(String("med")) || data.equalsIgnoreCase(String("m"))){
    _brightness = B_MEDIUM;
  }
  else if(data.equalsIgnoreCase(String("medium low")) || data.equalsIgnoreCase(String("mlow")) || data.equalsIgnoreCase(String("ml"))){
    _brightness = B_MEDIUM_LOW;
  }
  else if(data.equalsIgnoreCase(String("low")) || data.equalsIgnoreCase(String("l"))){
    _brightness = B_LOW;
  }
  else if(data.equalsIgnoreCase(String("very low")) || data.equalsIgnoreCase(String("vlow")) || data.equalsIgnoreCase(String("vl"))){
    _brightness = B_VERY_LOW;
  }
  else if(data.equalsIgnoreCase(String("extremely low")) || data.equalsIgnoreCase(String("elow")) || data.equalsIgnoreCase(String("el"))){
    _brightness = B_EXTREMELY_LOW;
  }
  else{
    Serial.print("Unknown brightness command value: ");
    Serial.println(data);
  }

  setColor(_currentColor);
}