Example #1
0
	/**
	 * Test string's toUpperCase
	 */
	void testToUpperCase() {
		// Lower case -> upper case
		{
			const String lowerCaseSource("hello@there-out*&%!1");
			const String lowerCase_toUpper = lowerCaseSource.toUpperCase();

            CPPUNIT_ASSERT(lowerCaseSource != lowerCase_toUpper);
			CPPUNIT_ASSERT_EQUAL(String("HELLO@THERE-OUT*&%!1"), lowerCase_toUpper);
		}

		// Mixed case -> lower case
		{
			const String mixedCaseSource("Hello @ Out^&There!");
			const String mixedCaseSource_toUpper = mixedCaseSource.toUpperCase();

			CPPUNIT_ASSERT(mixedCaseSource != mixedCaseSource_toUpper);
			CPPUNIT_ASSERT_EQUAL(String("HELLO @ OUT^&THERE!"), mixedCaseSource_toUpper);
		}

		// Upper case -> lower case
		{
			const String upperCaseSource("THERE@OUT*HELLO*&^%");
			const String upperCaseSource_toUpper = upperCaseSource.toUpperCase();

			// Identity
			CPPUNIT_ASSERT_EQUAL(upperCaseSource, upperCaseSource_toUpper);
		}
	}
Example #2
0
void loop()
{
    static uint32_t kit_hold = 0;

    if (millis() > kit_hold) {
        display::update_kit(0, 0, 0x20);
    }

    while (Console.available() > 0) {
        String input = Console.readStringUntil('\n');
        input.trim();
        if (!input.length()) {
            continue;
        }

        String command;
        int start_index = 0;
        int end_index = -1;
        parse_arg_string(input, start_index, end_index, command);
        command.toUpperCase();

        if (command == "BEEP") {
            int duration = 500;
            parse_arg_int(input, start_index, end_index, duration);
            Audio::play(duration);
        } else if (command == "DISPLAY") {
            int red = 0;
            int green = 0;
            int blue = 0;
            int duration = 1000;

            parse_arg_int(input, start_index, end_index, red);
            parse_arg_int(input, start_index, end_index, green);
            parse_arg_int(input, start_index, end_index, blue);
            parse_arg_int(input, start_index, end_index, duration);

            display::update_all(red, green, blue);
            if (duration) {
                kit_hold = millis() + duration;
            } else {
                kit_hold = 1UL << 31;
            }
        } else if (command == "HELP") {
            Console.print(F(
                              "Available commands: \n"
                              "BEEP [duration]\n"
                              "  duration: interger, in ms - default 500\n"
                              "DISPLAY <R> <G> <B> [duration]\n"
                              "  R, G, B: color values, 0-255 - default 255, 255, 255\n"
                              "  duration: integer, in ms - default 1000\n"
                          ));
        } else {
            Console.print(F("Unknown command: "));
            Console.print(input);
            Console.println();
        }
    }

    delay(200);
}
Example #3
0
// void addThreshold(Thr *t) {
//   thresholds.add(t);
// }
//
// Thr* getThreshold(const char* s) {
//   for (int i=0; i < thresholds.size(); i++) {
//     if (strcmp(thresholds.get(i)->id, s) == 0) return thresholds.get(i);
//   }
//   return NULL;
// }
//
// void removeThreshold(const char* id) {
//   for (int i=0; i < thresholds.size(); i++) {
//     if (strcmp(thresholds.get(i)->id, id) == 0) {
//       thresholds.remove(i);
//       return;
//     }
//   }
// }
//
// bool checkThresholds(LinkedList<Pair *> &values) {
//   return false;
// }
void addCommonValues(LinkedList<Pair *> *data) {
  data->add(new Pair("IP", String(WiFi.localIP().toString())));
  String chipId = String(ESP.getChipId(), HEX);
  chipId.toUpperCase();
  data->add(new Pair("CHIPID", chipId));
  data->add(new Pair("RUNTIME", String((millis() + rtcMemStore.getGenData(GEN_MSCOUNTER)) / 1000)));
}
static void COMM_command_received(String command) {
  //Serial.println("COMM command received: " + command);
  last_command = command;
  last_command.toUpperCase();
  last_arg = NO_ARGUMENT;
  COMM_check_all_commands();
}
static void COMM_command_received(String command, int arg) {
  //Serial.println("COMM command received: " + command + ", arg: " + String(arg));
  last_command = command;
  last_command.toUpperCase();
  last_arg = arg;
  COMM_check_all_commands();
}
Example #6
0
 String runString(CppiaCtx *ctx)
 {
    String val = strVal->runString(ctx);
    BCR_CHECK;
    if (UPPER)
       return val.toUpperCase();
    else
       return val.toLowerCase();
 }
Example #7
0
String SM125::toHexString(byte value) {

	String data = "";
	if (value < 16)
		data += "0";
	data += String(value, HEX);
	data.toUpperCase();
	return data;
}
void RingBuffer::prettyReadLine(String &lineToReturn){
    /*

    Return one line (terminated with \n) from the buffer, but in all uppercase
    with no leading or trailing whitespaces

    */
    readLine(lineToReturn);
    lineToReturn.trim();  // remove leading and trailing white space
    lineToReturn.toUpperCase();
}
Example #9
0
String DataClass::_filenameForSD(String name) {
  String filename;
  if (name.length()-1 > MAXFILENAME) {
    filename = name.substring(0, MAXFILENAME);
  }
  else {
    filename = name;
  }
  filename += ".txt";
  filename.toUpperCase();

  return filename;
}
Example #10
0
byte Convert::toHex(String input)
{
  input.toUpperCase();
  byte result = 0x00;
  //input checking
  if(input.length()==4) input = input.substring(2);
  else if(input.length()==3||input.length()>4) return 0x00;
  //
  result=this->value(input.charAt(0)); //first hex
  result=result<<4; //bitshift 4 places to the left
  result+=this->value(input.charAt(1)); //second hex
  return result;
}
void drawForecast(esp_ssd1306 *display, int x, int y, int dayIndex) {
  display->setTextAlignment(TEXT_ALIGN_CENTER);
  display->setFont(ArialMT_Plain_10);
  String day = wunderground.getForecastTitle(dayIndex).substring(0, 3);
  day.toUpperCase();
  display->drawString(x + 20, y, day);

  display->setFont(Meteocons_0_21);
  display->drawString(x + 20, y + 15, wunderground.getForecastIcon(dayIndex));

  display->setFont(ArialMT_Plain_16);
  display->drawString(x + 20, y + 37, wunderground.getForecastLowTemp(dayIndex) + "/" + wunderground.getForecastHighTemp(dayIndex));
  //display.drawString(x + 20, y + 51, );
  display->setTextAlignment(TEXT_ALIGN_LEFT);
}
// Connected to AP
void connectOk()
{
	// debug msg
	debugf("I'm CONNECTED to WiFi");

	mac = WifiStation.getMAC();
	mac.toUpperCase();
	for (int i = 2; i < mac.length(); i += 2)
		mac = mac.substring(0, i) + "-" + mac.substring(i++);

	debugf("mac: %s", mac.c_str());

	procTimer.initializeMs(6 * 60 * 1000, sendData).start();
	sendData();
}
Example #13
0
Result MDLFile::loadDocument (const File& file)
{
	destroyMDL();
	initMDL();
	MDLParser pa(*this);
    bool parseOk;
    String ext = file.getFileExtension().trimCharactersAtStart(".");
    if(file.hasFileExtension(".mdlx"))
    {
        parseOk = pa.parseMDLX(file);
    }
    else
    {
        parseOk = pa.parseMDL(file);
        if(StoredSettings::getInstance()->getIsUsingMDLX())
        {
            String mdlxPath = file.getParentDirectory().getFullPathName() + "/"
                + file.getFileNameWithoutExtension() + ".mdlx";

            File mdlxF(mdlxPath);
            if(mdlxF.existsAsFile())
            {
                pa.parseMDLX(mdlxF, true);
            }
        }
    }
    if (parseOk)
    {
        // success
        SAM_LOG("Opened " + ext.toUpperCase() + " file: " + getFilePath());
        setFile(file);
        setChangedFlag(false);
        isUntitledFile = false;
        md5 = MD5(file);

        // MDLHelper::addOutputDSPVarIfNotExists(*this);

        return Result::ok();
    }
    else
    {
        // fail
        String errorMsg = "ERROR: could not load " + ext + " file.";
        SAM_LOG(errorMsg);
        return Result::fail(errorMsg);
    }
}
Example #14
0
int main() {

	String foo = newString("This is FOO!");
	foo = foo.insertCharAt(&foo,'a',foo.length(&foo) - 1);
	foo.printString(&foo);


	foo = foo.substring(&foo,8,10);
	foo.printString(&foo);

	String bar = newString(" BAR");
	foo = foo.concat(&foo,&bar);
	foo.printString(&foo);

	StringArr foobar = split(&foo, " ");
	printf("%s\n",foobar[0]);
	printf("%s\n",foobar[1]);

	foo = foo.toLowerCase(&foo);
	bar = bar.toLowerCase(&bar);
	bar = bar.removeSpaces(&bar);
	foo.printString(&foo);
	bar.printString(&bar);

	if(foo.equals(&foo,&bar))
		printf("Same!\n");
	else
		printf("Not the same!\n");

	bar = newString("foo");

	if(foo.equals(&foo,&bar))
		printf("Same!\n");
	else
		printf("Not the same!\n");

	foo = foo.reverse(&foo);
	foo.printString(&foo);

	printf("%c\n",foo.charAt(&foo,1));

	bar = newString("bar");
	bar = bar.toUpperCase(&bar);
	printString(&bar);

}
Example #15
0
err_t HttpClient::onReceive(pbuf *buf)
{
	if (buf == NULL)
	{
		// Disconnected, close it
		TcpClient::onReceive(buf);
	}
	else
	{
		int startPos = 0;
		if (waitParse)
		{
			String http = NetUtils::pbufStrCopy(buf, 0, 4);
			http.toUpperCase();
			if (http == "HTTP" && code == 0)
			{
				int codeStart = NetUtils::pbufFindChar(buf, ' ', 4);
				int codeEnd = NetUtils::pbufFindChar(buf, ' ', codeStart + 1);
				if (codeStart != -1 && codeEnd != -1 && codeEnd - codeStart < 5)
				{
					String strCode = NetUtils::pbufStrCopy(buf, codeStart, codeEnd);
					code = strCode.toInt();
				}
				else
					code = 0;
			}
			int headerEnd = NetUtils::pbufFindStr(buf, "\r\n\r\n");
			if (headerEnd != -1)
			{
				debugf("Header pos: %d", headerEnd);
				startPos = headerEnd + 4;
				waitParse = false;
				if (headerEnd < NETWORK_MAX_HTTP_PARSING_LEN)
					parseHeaders(buf, headerEnd);
			}
		}

		writeRawData(buf, startPos);

		// Fire ReadyToSend callback
		TcpClient::onReceive(buf);
	}

	return ERR_OK;
}
//==============================================================================
void GeneratedCode::applyToCode (String& code,
                                 const String& fileNameRoot,
                                 const bool isForPreview,
                                 const String& oldFileWithUserData) const
{
    // header guard..
    String headerGuard ("__JUCER_HEADER_");
    headerGuard << className.toUpperCase().retainCharacters (T("ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
                << "_" << fileNameRoot.toUpperCase().retainCharacters (T("ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
                << "_" << String::toHexString (Random::getSystemRandom().nextInt()).toUpperCase()
                << "__";
    replaceTemplate (code, "headerGuard", headerGuard);

    replaceTemplate (code, "creationTime", Time::getCurrentTime().toString (true, true, true));

    replaceTemplate (code, "className", className);
    replaceTemplate (code, "constructorParams", constructorParams);
    replaceTemplate (code, "initialisers", getInitialiserList());

    replaceTemplate (code, "classDeclaration", getClassDeclaration());
    replaceTemplate (code, "privateMemberDeclarations", privateMemberDeclarations);
    replaceTemplate (code, "publicMemberDeclarations", getCallbackDeclarations() + "\n" + publicMemberDeclarations);

    replaceTemplate (code, "methodDefinitions", getCallbackDefinitions());

    replaceTemplate (code, "includeFilesH", getIncludeFileCode (includeFilesH));
    replaceTemplate (code, "includeFilesCPP", getIncludeFileCode (includeFilesCPP));

    replaceTemplate (code, "constructor", constructorCode);
    replaceTemplate (code, "destructor", destructorCode);

    if (! isForPreview)
    {
        replaceTemplate (code, "metadata", jucerMetadata);
        replaceTemplate (code, "staticMemberDefinitions", staticMemberDefinitions);
    }
    else
    {
        replaceTemplate (code, "metadata", T("  << Metadata isn't shown in the code preview >>\n"));
        replaceTemplate (code, "staticMemberDefinitions", T("// Static member declarations and resources would go here... (these aren't shown in the code preview)"));
    }

    copyAcrossUserSections (code, oldFileWithUserData);
}
void TimeClient::updateTime() {
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect("google.com", httpPort)) {
    Serial.println("connection failed");
    return;
  }
  
  // This will send the request to the server
  client.print(String("GET / HTTP/1.1\r\n") +
               String("Host: google.com\r\n") +
               String("Connection: close\r\n\r\n"));
  int repeatCounter = 0;
  while(!client.available() && repeatCounter < 10) {
    delay(1000); 
    Serial.println(".");
    repeatCounter++;
  }

  String line;

  int size = 0;
  client.setNoDelay(false);
  while(client.connected()) {
    while((size = client.available()) > 0) {
      line = client.readStringUntil('\n');
      line.toUpperCase();
      // example: 
      // date: Thu, 19 Nov 2015 20:25:40 GMT
      if (line.startsWith("DATE: ")) {
        Serial.println(line.substring(23, 25) + ":" + line.substring(26, 28) + ":" +line.substring(29, 31));
        int parsedHours = line.substring(23, 25).toInt();
        int parsedMinutes = line.substring(26, 28).toInt();
        int parsedSeconds = line.substring(29, 31).toInt();
        Serial.println(String(parsedHours) + ":" + String(parsedMinutes) + ":" + String(parsedSeconds));

        localEpoc = (parsedHours * 60 * 60 + parsedMinutes * 60 + parsedSeconds);
        Serial.println(localEpoc);
        localMillisAtUpdate = millis();
      }
    }
  }

}
Example #18
0
String cmd_Read(){
	String cmd = "";
	char ch;

	while (ch != '\r'){
		if(blueToothSerial.available()){
			ch = (char)blueToothSerial.read();
			if (ch != '\r' && ch != '\n')
				cmd.concat(ch);
		}
	}

	while(blueToothSerial.available())
		blueToothSerial.read();

	cmd.toUpperCase();
	//blueToothSerial.println(cmd);

	return cmd;
}
Example #19
0
String NfcTag::getUidString()
{
    String uidString = "";
    for (int i = 0; i < _uidLength; i++)
    {
        if (i > 0)
        {
            uidString += " ";
        }

        if (_uid[i] < 0xF)
        {
            uidString += "0";
        }

        uidString += String((unsigned int)_uid[i], (unsigned char)HEX);
    }
    uidString.toUpperCase();
    return uidString;
}
Example #20
0
Ultrasonic::Ultrasonic(const int trigPin, const int echoPin, String unit)
{
	pinMode(trigPin, OUTPUT);
	pinMode(echoPin, INPUT);
	_trigPin = trigPin;
	_echoPin = echoPin;
	unit.toUpperCase();
	if (unit == "MM")
	{
		_unit = 0;
	}
	else if(unit == "CM")
	{
		_unit = 1;
	}
	else
	{
		_unit = 2;
	}
	_duration = 0;
}
bool isAnimationFile(const char filename[]) {
	String fname = String(filename);
	fname.toUpperCase();
	
    if (filename[0] == '_')
        return false;

    if (filename[0] == '~')
        return false;

    if (filename[0] == '.')
        return false;

    //String filenameString = String(filename).toUpperCase();
    //String filenameString = fname;
    //if (filenameString.endsWith(".GIF") != 1)
    if (fname.endsWith(".GIF") != 1)
        return false;

    return true;
}
Example #22
0
void setupWiFi()
{
  WiFi.mode(WIFI_AP);

  // Do a little work to get a unique-ish name. Append the
  // last two bytes of the MAC (HEX'd) to "Thing-":
  uint8_t mac[WL_MAC_ADDR_LENGTH];
  WiFi.softAPmacAddress(mac);
  String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) +
                 String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
  macID.toUpperCase();
  String AP_NameString = "ESP8266 Thing " + macID;

  char AP_NameChar[AP_NameString.length() + 1];
  memset(AP_NameChar, 0, AP_NameString.length() + 1);

  for (int i=0; i<AP_NameString.length(); i++)
    AP_NameChar[i] = AP_NameString.charAt(i);

  WiFi.softAP(AP_NameChar, WiFiAPPSK);
}
void TimeClient::updateTime() {
  HTTPClient http;

  String url = "http://www.google.com/";
  const char * headerkeys[] = {"Date"} ;
  size_t headerkeyssize = sizeof(headerkeys)/sizeof(char*);
  // Based on Arduino core BasicHttpClient.ino example
  // https://github.com/esp8266/Arduino/blob/1588b45a8a15e4d3f1b42f052fc41590e9bec0bb/libraries/ESP8266HTTPClient/examples/BasicHttpClient/BasicHttpClient.ino
  // configure http client and url
  http.begin(url); //HTTP
  http.collectHeaders(headerkeys,headerkeyssize);
  // start connection and send HTTP header
  int httpCode = http.GET();
  // httpCode will be negative on error
  if(httpCode > 0) {
	  // HTTP header has been send and Server response header has been handled
	  USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
	  // file found at server
	  if ((httpCode == HTTP_CODE_OK)|| (httpCode == HTTP_CODE_FOUND)) {
		String payload = http.header("Date");
		USE_SERIAL.println(payload);
		http.end();
        payload.toUpperCase();
        // example:
      	// date: Thu, 19 Nov 2015 20:25:40 GMT
      	if (payload!=NULL) {
          Serial.println(payload.substring(17, 19) + ":" + payload.substring(20, 22) + ":" +payload.substring(23, 25));
          int parsedHours = payload.substring(17, 19).toInt();
          int parsedMinutes = payload.substring(20, 22).toInt();
          int parsedSeconds = payload.substring(23, 25).toInt();
          Serial.println(String(parsedHours) + ":" + String(parsedMinutes) + ":" + String(parsedSeconds));
          localEpoc = (parsedHours * 60 * 60 + parsedMinutes * 60 + parsedSeconds);
          Serial.println(localEpoc);
          localMillisAtUpdate = millis();
        }
      }
  }
}
Example #24
0
void autoUpdateIfForced(const char *ignore) {
  //Serial << F("Waiting for Wifi connection\n");
  if (waitForWifi(10000) != WL_CONNECTED) return;
  String urlGen = String(F("http://anker-bg.com/vlast3k/vesprino/"));
  String chipid =  String(ESP.getChipId(), 16);
  chipid.toUpperCase();
  String urlChip = String(F("http://anker-bg.com/vlast3k/vesprino/")) + chipid + String(F("/"));
  String forcedUpdateGen  = getHTTPFile(urlGen + F("forced.txt"));
  String forcedUpdateChip = getHTTPFile(urlChip + F("forced.txt"));
  uint32_t fc = atol(forcedUpdateChip.c_str());
  uint32_t fg = atol(forcedUpdateGen.c_str());
  uint32_t bn = atol(BUILD_NUM);
  Serial.printf("fg: %d, fc: %d, bn:%d\n", fg, fc, bn);
  if (bn >= fc && bn >= fg) return;
  String forcedUpdate = (fc >= fg) ? forcedUpdateChip : forcedUpdateGen;
  String urlUpdate    = (fc >= fg) ? urlChip : urlGen;
  if (DEBUG) {
    Serial << F("OTA: current Build: ") << atol(BUILD_NUM) << endl;
    Serial << F("OTA: forced  Build: ") << atol(forcedUpdate.c_str()) << endl;
  }
  //if (atol(BUILD_NUM) >= atol(forcedUpdateGen.c_str())) return;
  String url = urlUpdate + F("firmware") + forcedUpdate + F(".bin");
  doHttpUpdate(0, url.c_str());
}
Example #25
0
//----------------------------------------------------------------------------------------------------------------------
// methode : filenameContructor
// cree le nom de fichier pour acceder a la lettre
// le lettre est convertie en majuscules
// pas de verification !
String Tracer::fileNameConstructor( String sousDir, String fileNameBase ){
    fileNameBase.toUpperCase();
    return String(sousDir)+"/"+fileNameBase+String(".hex");
}
Example #26
0
/*For simplicity the configuration setting code uses four characters for each configuration choice. This makes things easier for
 comparison purposes.
 */
void handleConfigCmd() {
    int i;
    int newValue;
    float newFloatVal;
    char *newString;
    bool writeEEPROM = false;

    //Logger::debug("Cmd size: %i", ptrBuffer);
    if (ptrBuffer < 6)
        return; //4 digit command, =, value is at least 6 characters
    cmdBuffer[ptrBuffer] = 0; //make sure to null terminate
    String cmdString = String();
    unsigned char whichEntry = '0';
    i = 0;

    while (cmdBuffer[i] != '=' && i < ptrBuffer) {
        cmdString.concat(String(cmdBuffer[i++]));
    }
    i++; //skip the =
    if (i >= ptrBuffer)
    {
        Logger::console("Command needs a value..ie TORQ=3000");
        Logger::console("");
        return; //or, we could use this to display the parameter instead of setting
    }

    // strtol() is able to parse also hex values (e.g. a string "0xCAFE"), useful for enable/disable by device id
    newValue = strtol((char *) (cmdBuffer + i), NULL, 0); //try to turn the string into a number
    newFloatVal = strtof((char *) (cmdBuffer + i), 0);
    newString = (char *)(cmdBuffer + i); //leave it as a string

    cmdString.toUpperCase();

    if (cmdString == String("CANSPEED")) {
        if (newValue > 0 && newValue <= 1000000)
        {
            Logger::console("Setting CAN Baud Rate to %i", newValue);
            settings.canSpeed = newValue;
            Can0.begin(settings.canSpeed, 255);
            writeEEPROM = true;
        }
        else Logger::console("Invalid baud rate! Enter a value 1 - 1000000");
    } else if (cmdString == String("CANRXBASE")) {
        if (newValue > 0 && newValue <= 0x7FF)
        {
            Logger::console("Setting CAN RX Base to %X", newValue);
            settings.canBaseRx = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid base address. Must be more than 0 and less than 0x7FF");
    } else if (cmdString == String("CANTXBASE")) {
        if (newValue > 0 && newValue <= 0x7FF)
        {
            Logger::console("Setting CAN TX Base to %X", newValue);
            settings.canBaseTx = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid base address. Must be more than 0 and less than 0x7FF");
    } else if (cmdString == String("BUSVOLTBIAS")) {
        if (newValue > 0 && newValue <= 0xFFFF)
        {
            Logger::console("Setting bus voltage ADC bias to %i", newValue);
            settings.busVoltageBias = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid ADC bias value. Must be between 0 and 65535");
    } else if (cmdString == String("CURR1BIAS")) {
        if (newValue > 0 && newValue <= 0xFFFF)
        {
            Logger::console("Setting current 1 ADC bias to %i", newValue);
            settings.current1Bias = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid ADC bias value. Must be between 0 and 65535");
    } else if (cmdString == String("CURR2BIAS")) {
        if (newValue > 0 && newValue <= 0xFFFF)
        {
            Logger::console("Setting current 2 ADC bias to %i", newValue);
            settings.current2Bias = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid ADC bias value. Must be between 0 and 65535");
    } else if (cmdString == String("INVTEMP1BIAS")) {
        if (newValue > 0 && newValue <= 0xFFFF)
        {
            Logger::console("Setting temp 1 bias ADC bias to %i", newValue);
            settings.inverterTemp1Bias = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid ADC bias value. Must be between 0 and 65535");
    } else if (cmdString == String("INVTEMP2BIAS")) {
        if (newValue > 0 && newValue <= 0xFFFF)
        {
            Logger::console("Setting temp 2 bias ADC bias to %i", newValue);
            settings.inverterTemp2Bias = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid ADC bias value. Must be between 0 and 65535");
    } else if (cmdString == String("BUSVOLTSCALE")) {
        if (newFloatVal > 0.0f && newFloatVal <= 10.0f)
        {
            Logger::console("Setting Bus voltage scaling factor to %f", newFloatVal);
            settings.busVoltageScale = (uint32_t)(newFloatVal * 65536.0f);
            writeEEPROM = true;
        }
        else Logger::console("Please enter a scaling factor between 0 and 10.0");
    } else if (cmdString == String("CURR1SCALE")) {
        if (newFloatVal > 0.0f && newFloatVal <= 10.0f)
        {
            Logger::console("Setting current sensor 1 scaling factor to %f", newFloatVal);
            settings.current1Scale = (uint32_t)(newFloatVal * 65536.0f);
            writeEEPROM = true;
        }
        else Logger::console("Please enter a scaling factor between 0 and 10.0");
    } else if (cmdString == String("CURR2SCALE")) {
        if (newFloatVal > 0.0f && newFloatVal <= 10.0f)
        {
            Logger::console("Setting current sensor 2 scaling factor to %f", newFloatVal);
            settings.current2Scale = (uint32_t)(newFloatVal * 65536.0f);
            writeEEPROM = true;
        }
        else Logger::console("Please enter a scaling factor between 0 and 10.0");
    } else if (cmdString == String("INVTEMP1SCALE")) {
        if (newFloatVal > 0.0f && newFloatVal <= 10.0f)
        {
            Logger::console("Setting temperature sensor 1 scaling factor to %f", newFloatVal);
            settings.inverterTemp1Scale = (uint32_t)(newFloatVal * 65536.0f);
            writeEEPROM = true;
        }
        else Logger::console("Please enter a scaling factor between 0 and 10.0");
    } else if (cmdString == String("INVTEMP2SCALE")) {
        if (newFloatVal > 0.0f && newFloatVal <= 10.0f)
        {
            Logger::console("Setting temperature sensor 2 scaling factor to %f", newFloatVal);
            settings.inverterTemp2Scale = (uint32_t)(newFloatVal * 65536.0f);
            writeEEPROM = true;
        }
        else Logger::console("Please enter a scaling factor between 0 and 10.0");
    } else if (cmdString == String("MOTORTIMECONST")) {
        if (newFloatVal > 0.0f && newFloatVal <= 1.0f)
        {
            Logger::console("Setting motor time constant to %f", newFloatVal);
            settings.rotorTimeConst = (uint32_t)(newFloatVal * 65536.0f);
            writeEEPROM = true;
        }
        else Logger::console("Please enter a time constant more than 0 and less than 1.0");
    } else if (cmdString == String("MOTORTYPE")) {
        if (newValue >= 0 && newValue <= 2)
        {
            Logger::console("Setting motor type to %i", newValue);
            settings.motorType = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid motor type. Please enter 0, 1, or 2");
    } else if (cmdString == String("CTRLTYPE")) {
        if (newValue >= 0 && newValue <= 1)
        {
            Logger::console("Setting control type to %i", newValue);
            settings.controlType = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid control type. Please enter 0 or 1");
    } else if (cmdString == String("HALLAB")) {
        if (newValue >= 0 && newValue <= 3)
        {
            Logger::console("Setting HALL AB to %i", newValue);
            settings.hallAB = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid digital input. Range is 0 to 3");
    } else if (cmdString == String("HALLBC")) {
        if (newValue >= 0 && newValue <= 3)
        {
            Logger::console("Setting HALL BC to %i", newValue);
            settings.hallBC = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid digital input. Range is 0 to 3");
    } else if (cmdString == String("HALLCA")) {
        if (newValue >= 0 && newValue <= 3)
        {
            Logger::console("Setting HALL CA to %i", newValue);
            settings.hallCA = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid digital input. Range is 0 to 3");
    } else if (cmdString == String("MOTORNUMPOLES")) {
        if (newValue > 0 && newValue <= 40)
        {
            Logger::console("Setting motor pole pairs to %i", newValue);
            settings.numPoles = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid number of pole pairs. Must be at least one and less than 40");
    } else if (cmdString == String("ENCODERCOUNT")) {
        if (newValue > 0 && newValue <= 100000)
        {
            Logger::console("Setting encoder pulses per rev to %i", newValue);
            settings.encoderCount = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid encoder count. Value must be more than 0 and less than 100000");
    } else if (cmdString == String("ENCODERDIR")) {
        if (newValue >= 0 && newValue <= 1)
        {
            Logger::console("Setting encoder direction to %i", newValue);
            settings.encoderDirection = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid encoder direction. Value must be either 0 or 1");
    } else if (cmdString == String("PIDKP")) {
        if (newFloatVal >= 0.0f && newFloatVal <= 10.0f)
        {
            Logger::console("Setting PID P coef to %f", newFloatVal);
            settings.pid_KP = (uint32_t)(newFloatVal * 65536.0f);
            writeEEPROM = true;
        }
        else Logger::console("Please enter a coefficient between 0.0 and 10.0");
    } else if (cmdString == String("PIDKI")) {
        if (newFloatVal >= 0.0f && newFloatVal <= 10.0f)
        {
            Logger::console("Setting PID I coef to %f", newFloatVal);
            settings.pid_KI = (uint32_t)(newFloatVal * 65536.0f);
            writeEEPROM = true;
        }
        else Logger::console("Please enter a coefficient between 0.0 and 10.0");
    } else if (cmdString == String("PIDKD")) {
        if (newFloatVal >= 0.0f && newFloatVal <= 10.0f)
        {
            Logger::console("Setting PID D coef to %f", newFloatVal);
            settings.pid_KD = (uint32_t)(newFloatVal * 65536.0f);
            writeEEPROM = true;
        }
        else Logger::console("Please enter a coefficient between 0.0 and 10.0");
    } else if (cmdString == String("VHZRPM")) {
        if (newValue >= 0 && newValue <= settings.maxRPM)
        {
            Logger::console("Setting V/Hz target RPM to %i", newValue);
            controllerStatus.rpm = newValue;
            setVHzSpeed(newValue);
        }
        else Logger::console("Invalid max RPM. Must be positive and less than your max RPM setting");
    } else if (cmdString == String("ANGLEOFFSET")) {
        if (newValue >= 0 && newValue <= 511)
        {
            Logger::console("Setting angular offset to %i", newValue);
            settings.thetaOffset = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid angular offset. Must be between 0 and 511");
    } else if (cmdString == String("MAXRPM")) {
        if (newValue > 0 && newValue <= 30000)
        {
            Logger::console("Setting max RPM to %i", newValue);
            settings.maxRPM = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid max RPM. Must be more than 0 and less than 30000");
    } else if (cmdString == String("MAXTRQ")) {
        if (newValue > 0 && newValue <= 30000)
        {
            Logger::console("Setting max torque to %i", newValue);
            settings.maxTorque = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid max torque. Must be more than 0 and less than 30000");
    } else if (cmdString == String("MAXAMPDRIVE")) {
        if (newValue > 0 && newValue <= 20000)
        {
            Logger::console("Setting max drive amperage to %i", newValue);
            settings.maxAmpsDrive = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid max drive amperage. Must be more than 0 and less than 20000");
    } else if (cmdString == String("MAXAMPREGEN")) {
        if (newValue > 0 && newValue <= 20000)
        {
            Logger::console("Setting max regen amperage to %i", newValue);
            settings.maxAmpsDrive = newValue;
            writeEEPROM = true;
        }
        else Logger::console("Invalid max regen amperage. Must be more than 0 and less than 20000");
    } else if (cmdString == String("LOGLEVEL")) {
        switch (newValue) {
        case 0:
            Logger::setLoglevel(Logger::Debug);
            Logger::console("setting loglevel to 'debug'");
            writeEEPROM = true;
            break;
        case 1:
            Logger::setLoglevel(Logger::Info);
            Logger::console("setting loglevel to 'info'");
            writeEEPROM = true;
            break;
        case 2:
            Logger::console("setting loglevel to 'warning'");
            Logger::setLoglevel(Logger::Warn);
            writeEEPROM = true;
            break;
        case 3:
            Logger::console("setting loglevel to 'error'");
            Logger::setLoglevel(Logger::Error);
            writeEEPROM = true;
            break;
        case 4:
            Logger::console("setting loglevel to 'off'");
            Logger::setLoglevel(Logger::Off);
            writeEEPROM = true;
            break;
        }
    }
    else {
        Logger::console("Unknown command");
    }
    if (writeEEPROM)
    {
        EEPROM.write(EEPROM_PAGE, settings);
    }
}
bool  ZeroStreamListener::ExecCommand(const Command& command, bool wantAnswer)
{
  if(wantAnswer) PublishSingleton = UNKNOWN_COMMAND;

  bool canPublish = true; // флаг, что можем публиковать

   size_t argsCnt = command.GetArgsCount();
  
  if(command.GetType() == ctGET) 
  {
     PublishSingleton = NOT_SUPPORTED;      
    if(!argsCnt) // нет аргументов
    {
      PublishSingleton = PARAMS_MISSED;
    }
    else
    {
      if(argsCnt < 1)
      {
        // мало параметров
        PublishSingleton = PARAMS_MISSED;
        
      } // if
      else
      {
        String t = command.GetArg(0); // получили команду
        t.toUpperCase();
        if(t == PING_COMMAND) // пинг
        {
          PublishSingleton.Status = true;
          PublishSingleton = PONG;
          PublishSingleton.AddModuleIDToAnswer = false;
        } // if
        else
        if(t == UNI_RF_CHANNEL_COMMAND)
        {
          PublishSingleton.Status = true;
          PublishSingleton = UNI_RF_CHANNEL_COMMAND;
          PublishSingleton << PARAM_DELIMITER;
          PublishSingleton << UniDispatcher.GetRFChannel();
          PublishSingleton.AddModuleIDToAnswer = false;          
        }
        #if defined(USE_UNIVERSAL_SENSORS) && defined(UNI_USE_REGISTRATION_LINE)
        else
        if(t == UNI_SEARCH) // поиск универсального модуля на линии регистрации
        {
          PublishSingleton.AddModuleIDToAnswer = false;
          
          if(uniRegistrator.IsModulePresent())
          {
            // датчик найден, отправляем его внутреннее состояние
            PublishSingleton.Status = true;

            UniRawScratchpad scratch;
            uniRegistrator.CopyScratchpad(&scratch);
            byte* raw = (byte*) &scratch;
            
            PublishSingleton = "";
            
            // теперь пишем весь скратчпад вызывающему, пущай сам разбирается, как с ним быть
            for(byte i=0;i<sizeof(UniRawScratchpad);i++)
            {
              PublishSingleton << WorkStatus::ToHex(raw[i]);
            } // for

          } // if
          else
          {
            // датчика нету
            PublishSingleton = UNI_NOT_FOUND;
          } // else
        }
        #endif // UNI_USE_REGISTRATION_LINE
        else
        if(t == ID_COMMAND)
        {
          PublishSingleton.Status = true;
          PublishSingleton.AddModuleIDToAnswer = false;
          PublishSingleton = ID_COMMAND; 
          PublishSingleton << PARAM_DELIMITER << MainController->GetSettings()->GetControllerID();
        }
        else
        if(t == WIRED_COMMAND) // получить количество жёстко указанных в прошивке обычных датчиков
        {
          PublishSingleton.Status = true;
          PublishSingleton.AddModuleIDToAnswer = false;
          PublishSingleton = WIRED_COMMAND;

          PublishSingleton << PARAM_DELIMITER << UniDispatcher.GetHardCodedSensorsCount(uniTemp);
          PublishSingleton << PARAM_DELIMITER << UniDispatcher.GetHardCodedSensorsCount(uniHumidity);
          PublishSingleton << PARAM_DELIMITER << UniDispatcher.GetHardCodedSensorsCount(uniLuminosity);
          PublishSingleton << PARAM_DELIMITER << UniDispatcher.GetHardCodedSensorsCount(uniSoilMoisture);
          PublishSingleton << PARAM_DELIMITER << UniDispatcher.GetHardCodedSensorsCount(uniPH);
          //TODO: Тут остальные типы датчиков указывать !!!
                     
        }
        else
        if(t == UNI_COUNT_COMMAND) // получить количество зарегистрированных универсальных датчиков
        {
          PublishSingleton.Status = true;
          PublishSingleton.AddModuleIDToAnswer = false;
          PublishSingleton = UNI_COUNT_COMMAND;

          PublishSingleton << PARAM_DELIMITER << UniDispatcher.GetUniSensorsCount(uniTemp);
          PublishSingleton << PARAM_DELIMITER << UniDispatcher.GetUniSensorsCount(uniHumidity);
          PublishSingleton << PARAM_DELIMITER << UniDispatcher.GetUniSensorsCount(uniLuminosity);
          PublishSingleton << PARAM_DELIMITER << UniDispatcher.GetUniSensorsCount(uniSoilMoisture);
          PublishSingleton << PARAM_DELIMITER << UniDispatcher.GetUniSensorsCount(uniPH);
          //TODO: Тут остальные типы датчиков указывать !!!
                     
        }

        
        else
        if(t == SMS_NUMBER_COMMAND) // номер телефона для управления по СМС
        {
          PublishSingleton.Status = true;
          PublishSingleton.AddModuleIDToAnswer = false;
          PublishSingleton = SMS_NUMBER_COMMAND; 
          PublishSingleton << PARAM_DELIMITER << MainController->GetSettings()->GetSmsPhoneNumber();
        }
  
        else if(t == STATUS_COMMAND) // получить статус всего железного добра
        {
          if(wantAnswer)
          {
            // входящий поток установлен, значит, можем писать прямо в него
            canPublish = false; // скажем, что мы не хотим публиковать через контроллер - будем писать в поток сами
            Stream* pStream = command.GetIncomingStream();
            pStream->print(OK_ANSWER);
            pStream->print(COMMAND_DELIMITER);

            WORK_STATUS.WriteStatus(pStream,true); // просим записать статус

            // тут можем писать остальные статусы, типа показаний датчиков и т.п.:

            size_t modulesCount = MainController->GetModulesCount(); // получаем кол-во зарегистрированных модулей

          //  const char* noDataByte = "FF"; // байт - нет данных с датчика

            // пробегаем по всем модулям
            String moduleName;
            moduleName.reserve(20);
            
            for(size_t i=0;i<modulesCount;i++)
            {
              yield(); // немного даём поработать другим модулям

              AbstractModule* mod = MainController->GetModule(i);
             // if(mod == this) // себя пропускаем
             //   continue;

              // проверяем, не пустой ли модуль. для этого смотрим, сколько у него датчиков вообще
              uint8_t tempCount = mod->State.GetStateCount(StateTemperature);
              uint8_t humCount = mod->State.GetStateCount(StateHumidity);
              uint8_t lightCount = mod->State.GetStateCount(StateLuminosity);
              uint8_t waterflowCountInstant = mod->State.GetStateCount(StateWaterFlowInstant);
              uint8_t waterflowCount = mod->State.GetStateCount(StateWaterFlowIncremental);
              uint8_t soilMoistureCount = mod->State.GetStateCount(StateSoilMoisture); 
              uint8_t phCount = mod->State.GetStateCount(StatePH); 
              
              //TODO: тут другие типы датчиков!!!

              if((tempCount + humCount + lightCount + waterflowCountInstant + waterflowCount + soilMoistureCount + phCount) < 1) // пустой модуль, без интересующих нас датчиков
                continue;

              uint8_t flags = 0;
              if(tempCount) flags |= StateTemperature;
              if(humCount) flags |= StateHumidity;
              if(lightCount) flags |= StateLuminosity;
              if(waterflowCountInstant) flags |= StateWaterFlowInstant;
              if(waterflowCount) flags |= StateWaterFlowIncremental;
              if(soilMoistureCount) flags |= StateSoilMoisture;
              if(phCount) flags |= StatePH;
              //TODO: Тут другие типы датчиков!!!

            // показание каждого модуля идут так:
            
            // 1 байт - флаги о том, какие датчики есть
             pStream->write(WorkStatus::ToHex(flags));
            
            // 1 байт - длина ID модуля
              moduleName = mod->GetID();
              uint8_t mnamelen = moduleName.length();
              pStream->write(WorkStatus::ToHex(mnamelen));
            // далее идёт имя модуля
              pStream->write(moduleName.c_str());
            
            
              // затем идут данные из модуля, сначала - показания температуры, если они есть
              PrintSensorsValues(tempCount,StateTemperature,mod,pStream);
              // затем идёт кол-во датчиков влажности, если они есть
              PrintSensorsValues(humCount,StateHumidity,mod,pStream);
              // затем идут показания датчиков освещенности, если они есть
              PrintSensorsValues(lightCount,StateLuminosity,mod,pStream);
              // затем идут моментальные показания датчиков расхода воды, если они есть
              PrintSensorsValues(waterflowCountInstant,StateWaterFlowInstant,mod,pStream);
              // затем идут накопительные показания датчиков расхода воды, если они есть
              PrintSensorsValues(waterflowCount,StateWaterFlowIncremental,mod,pStream);
              // затем идут датчики влажности почвы, если они есть
              PrintSensorsValues(soilMoistureCount,StateSoilMoisture,mod,pStream);
              // затем идут датчики pH, если они есть
              PrintSensorsValues(phCount,StatePH,mod,pStream);
            
              //TODO: тут другие типы датчиков!!!

            } // for
            

            pStream->print(NEWLINE); // пишем перевод строки
            
          } // wantAnswer
          
        } // STATUS_COMMAND     
        else if(t == REGISTERED_MODULES_COMMAND) // пролистать зарегистрированные модули
        {
          PublishSingleton.AddModuleIDToAnswer = false;
          PublishSingleton.Status = true;
          PublishSingleton = F("");
          size_t cnt = MainController->GetModulesCount();
          for(size_t i=0;i<cnt;i++)
          {
            AbstractModule* mod = MainController->GetModule(i);

            if(mod != this)
            {
              if(PublishSingleton.Text.length())
                PublishSingleton << PARAM_DELIMITER;
              
              PublishSingleton << mod->GetID();
             
            }// if
              
          } // for
        }
        else
        {
            // неизвестная команда
        } // else
        
          
      } // else
    } // elsse
    
  } // ctGET
  else
  if(command.GetType() == ctSET)
  {

    if(!argsCnt) // нет аргументов
    {
      PublishSingleton = PARAMS_MISSED;
    }
    else
    {
      if(argsCnt < 2)
      {
        // мало параметров
        PublishSingleton = PARAMS_MISSED;
        String t = command.GetArg(0);    

        if(t == RESET_COMMAND)
        {
          resetFunc(); // ресетимся, писать в ответ ничего не надо
        } // RESET_COMMAND
        else
        if(t == F("AUTO")) // CTSET=0|AUTO - перевести в автоматический режим
        {
          // очищаем общий буфер ответов
          PublishSingleton = "";

          // выполняем команды
          ModuleInterop.QueryCommand(ctSET, F("STATE|MODE|AUTO"),false,false);
          ModuleInterop.QueryCommand(ctSET, F("WATER|MODE|AUTO"),false,false);
          ModuleInterop.QueryCommand(ctSET, F("LIGHT|MODE|AUTO"),false,false);

          // говорим, что выполнили
          PublishSingleton = REG_SUCC;
          PublishSingleton.Status = true;
        
        } // AUTO
                
      } // if
      else
      {
        String t = command.GetArg(0); // получили команду
        
      #ifdef USE_REMOTE_MODULES 
      if(t == ADD_COMMAND) // запросили регистрацию нового модуля
       {
          // ищем уже зарегистрированный
          String reqID = command.GetArg(1);
          AbstractModule* mod = c->GetModuleByID(reqID);
          if(mod)
          {
            // модуль уже зарегистрирован
            PublishSingleton = REG_ERR; 
            PublishSingleton << PARAM_DELIMITER << reqID;
          } // if
          else
          {
            // регистрируем новый модуль
            RemoteModule* remMod = new RemoteModule(reqID); 
            c->RegisterModule(remMod);
            PublishSingleton.Status = true;
            PublishSingleton = REG_SUCC; 
            PublishSingleton << PARAM_DELIMITER << reqID;

          } // else
       }
       
       else 
       #endif
       if(t == SMS_NUMBER_COMMAND) // номер телефона для управления по SMS
       {
          GlobalSettings* sett = MainController->GetSettings();
          sett->SetSmsPhoneNumber(command.GetArg(1));
          sett->Save();
          PublishSingleton.Status = true;
          PublishSingleton = SMS_NUMBER_COMMAND; 
          PublishSingleton << PARAM_DELIMITER << REG_SUCC;
          
       }
       else
       if(t == UNI_RF_CHANNEL_COMMAND)
       {
          byte ch = atoi(command.GetArg(1));
          UniDispatcher.SetRFChannel(ch);

          #ifdef USE_NRF_GATE
            nrfGate.SetChannel(ch);
          #endif
          
          PublishSingleton.Status = true;
          PublishSingleton = UNI_RF_CHANNEL_COMMAND; 
          PublishSingleton << PARAM_DELIMITER << REG_SUCC;
        
       }
        #if defined(USE_UNIVERSAL_SENSORS) && defined(UNI_USE_REGISTRATION_LINE)
        else
        if(t == UNI_REGISTER) // зарегистрировать универсальный модуль, висящий на линии
        {
          PublishSingleton.AddModuleIDToAnswer = false;

              if(uniRegistrator.IsModulePresent())
              {
                // модуль есть на линии, регистрируем его в системе.
                // сначала вычитываем переданный скратчпад и назначаем его модулю.
                // считаем, что на вызывающей стороне разобрались, что с чем, с остальным
                // разберётся модуль регистрации.
                const char* scratchData = command.GetArg(1);
                // теперь конвертируем данные скратчпада из текстового представления в нормальное
                char buff[3] = {0};
                uint8_t len = strlen(scratchData);

                UniRawScratchpad scratch;
                byte* raw = (byte* )&scratch;

                for(uint8_t i=0;i<len;i+=2)
                {
                  buff[0] = scratchData[i];
                  buff[1] = scratchData[i+1];
                  *raw = WorkStatus::FromHex(buff);
                  raw++;
                } // for
                
                if(uniRegistrator.SetScratchpadData(&scratch))
                {
                  uniRegistrator.Register();
                              
                  PublishSingleton.Status = true;
                  PublishSingleton = REG_SUCC;
                } // if
                else
                {
                   // разные типы скратчпадов, возможно, подсоединили другой модуль
                   PublishSingleton = UNI_DIFFERENT_SCRATCHPAD;
                }
                
              } // if
              else
              {
                // модуля нет на линии
                PublishSingleton = UNI_NOT_FOUND;
              }
              
          
        } // UNI_REGISTER
        #endif // UNI_USE_REGISTRATION_LINE
       
       else if(t == ID_COMMAND)
       {
          //String newID = command.GetArg(1);
          MainController->GetSettings()->SetControllerID((uint8_t)atoi(command.GetArg(1)));
          PublishSingleton.Status = true;
          PublishSingleton = ID_COMMAND; 
          PublishSingleton << PARAM_DELIMITER << REG_SUCC;
        
       }       
       #ifdef USE_DS3231_REALTIME_CLOCK
       else if(t == SETTIME_COMMAND)
       {
         // установка даты/времени
         String rawDatetime = command.GetArg(1);
         int8_t idx = rawDatetime.indexOf(F(" "));
         String tm, dt;
         if(idx != -1)
         {
          dt = rawDatetime.substring(0,idx);
          tm = rawDatetime.substring(idx+1);

            String month,day,year;
            String hour,minute,sec;
            idx = dt.indexOf(F("."));
            if(idx != -1)
             {
              day = dt.substring(0,idx);
              dt = dt.substring(idx+1);
             }
             
            idx = dt.indexOf(F("."));
            if(idx != -1)
             {
              month = dt.substring(0,idx);
              year = dt.substring(idx+1);
             }

             idx = tm.indexOf(F(":"));
             if(idx != -1)
             {
              hour = tm.substring(0,idx);
              tm = tm.substring(idx+1);
             }

             idx = tm.indexOf(F(":"));
             if(idx != -1)
             {
              minute = tm.substring(0,idx);
              sec = tm.substring(idx+1);
             }

             // вычисляем день недели
             int yearint = year.toInt();
             int monthint = month.toInt();
             int dayint = day.toInt();
             
             int dow;
             byte mArr[12] = {6,2,2,5,0,3,5,1,4,6,2,4};
             dow = (yearint % 100);
             dow = dow*1.25;
             dow += dayint;
             dow += mArr[monthint-1];
             
             if (((yearint % 4)==0) && (monthint<3))
               dow -= 1;
               
             while (dow>7)
               dow -= 7;             

            
             DS3231Clock cl = MainController->GetClock();
             cl.setTime(sec.toInt(),minute.toInt(),hour.toInt(),dow,dayint,monthint,yearint);

             PublishSingleton.Status = true;
             PublishSingleton = REG_SUCC;
         } // if
       }
       #endif
       else
       {
         // неизвестная команда
       } // else
      } // else argsCount > 1
    } // else
    
  } // if
 
 // отвечаем на команду
 if(canPublish) // можем публиковать
  MainController->Publish(this,command);
 else
  PublishSingleton = F(""); // просто очищаем общий буфер
    
  return PublishSingleton.Status;
}
Example #28
0
void receiveProtocolIT_TX(unsigned int changeCount) {
#define TX_ONE    520
#define TX_ZERO   1250
#define TX_GLITCH  100
#define TX_MESSAGELENGTH 44

  byte i;
  unsigned long code = 0;

#ifdef USE_IT_TX
  message = "TX";
#else
  message = "W00";
#endif

  for (i = 0; i <= 14; i = i + 2)
  {
    if ((timingsTX[i] > TX_ZERO - TX_GLITCH) && (timingsTX[i] < TX_ZERO + TX_GLITCH))    {
      code <<= 1;
    }
    else if ((timingsTX[i] > TX_ONE - TX_GLITCH) && (timingsTX[i] < TX_ONE + TX_GLITCH)) {
      code <<= 1;
      code |= 1;
    }
    else {
      return;
    }
  }

  // Startsequence 0000 1010 = 0xA
  if (code != 10) {
    return;
  }

  message += String(code,HEX);
  code = 0;

  // Sensor type 0000 = Temp / 1110 = Humidity
  for (i = 16; i <= 22; i = i + 2)
  {
    if ((timingsTX[i] > TX_ZERO - TX_GLITCH) && (timingsTX[i] < TX_ZERO + TX_GLITCH))    {
      code <<= 1;
    }
    else if ((timingsTX[i] > TX_ONE - TX_GLITCH) && (timingsTX[i] < TX_ONE + TX_GLITCH)) {
      code <<= 1;
      code |= 1;
    }
    else {
      return;
    }
  }

  message += String(code,HEX);
  code = 0;

  // Sensor adress
  for (i = 24; i <= 38; i = i + 2)
  {
    if ((timingsTX[i] > TX_ZERO - TX_GLITCH) && (timingsTX[i] < TX_ZERO + TX_GLITCH))    {
      code <<= 1;
    }
    else if ((timingsTX[i] > TX_ONE - TX_GLITCH) && (timingsTX[i] < TX_ONE + TX_GLITCH)) {
      code <<= 1;
      code |= 1;
    }
    else {
      return;
    }
  }
  message += String(code,HEX);
  code = 0;

  // Temp or Humidity
  for (i = 40; i <= 62; i = i + 2)
  {
    if ((timingsTX[i] > TX_ZERO - TX_GLITCH) && (timingsTX[i] < TX_ZERO + TX_GLITCH))    {
      code <<= 1;
    }
    else if ((timingsTX[i] > TX_ONE - TX_GLITCH) && (timingsTX[i] < TX_ONE + TX_GLITCH)) {
      code <<= 1;
      code |= 1;
    }
    else {
      return;
    }
  }
  message += String(code,HEX);
  code = 0;

  // Repeated Bytes temp / Humidity
  for (i = 64; i <= 78; i = i + 2)
  {
    if ((timingsTX[i] > TX_ZERO - TX_GLITCH) && (timingsTX[i] < TX_ZERO + TX_GLITCH))    {
      code <<= 1;
    }
    else if ((timingsTX[i] > TX_ONE - TX_GLITCH) && (timingsTX[i] < TX_ONE + TX_GLITCH)) {
      code <<= 1;
      code |= 1;
    }
    else {
      return;
    }
  }
  message += String(code,HEX);
  code = 0;

  // Checksum
  for (i = 80; i <= changeCount; i = i + 2)
  {
    if ((timingsTX[i] > TX_ZERO - TX_GLITCH) && (timingsTX[i] < TX_ZERO + TX_GLITCH))    {
      code <<= 1;
    }
    else if ((timingsTX[i] > TX_ONE - TX_GLITCH) && (timingsTX[i] < TX_ONE + TX_GLITCH)) {
      code <<= 1;
      code |= 1;
    }
    else {
      return;
    }
  }
  message += String(code,HEX);
  
  message.toUpperCase();

  available = true;
  return;
}
void FTPServerConnection::onCommand(String cmd, String data)
{
	cmd.toUpperCase();
	debugf("FTP : cmd = %s, data = %s",cmd.c_str(),data.c_str());
	// We ready to quit always :)
	if (cmd == "QUIT")
	{
		response(221);
		close();
		return;
	}

	// Strong security check :)
	if (state == eFCS_Authorization)
	{
		if (cmd == "USER")
		{
			userName = data;
			response(331);
		}
		else if (cmd == "PASS")
		{
			if (server->checkUser(userName, data))
			{
				userName = "";
				state = eFCS_Active;
				response(230);
			}
			else
				response(430);
		}
		else
		{
			response(530);
		}
		return;
	}

	if (state == eFCS_Active)
	{
		if (cmd == "SYST")
		{
			response(215, "Windows_NT: Sming Framework"); // Why not? It's look like Windows :)
		}
		else if (cmd == "PWD")
		{
			response(257, "\"/\"");
		}
		else if (cmd == "PORT")
		{
			cmdPort(data);
		}
		else if (cmd == "EPRT")
		{
			cmdEPRT(data);
		}
		else if (cmd == "CWD")
		{
			if (data == "/")
			{
				directoryPrefix = "";
				response(250);
			}
			else
			{
				directoryPrefix = directoryPrefix + data + "/";
				response(250);
			}
		}
		else if (cmd == "TYPE")
		{
//			response(250);
			response(200);
		}
		/*else if (cmd == "SIZE")
		{
			response(213, String(fileGetSize(makeFileName(data, false))));
		}*/
		else if (cmd == "DELE")
		{
			String name = makeFileName(data, false);
			if (fileExist(name))
			{
				fileDelete(name);
				response(250);
			}
			else
				response(550);
		}
		/*else if (cmd == "RNFR") // Bugs!
		{
			renameFrom = data;
			response(350);
		}
		else if (cmd == "RNTO")
		{
			if (fileExist(renameFrom))
			{
				fileRename(renameFrom, data);
				response(250);
			}
			else
				response(550);
		}*/
		else if (cmd == "RETR")
		{
			String name = makeFileName(data, false);
			if (fileExist(name))
			{
				createDataConnection(new FTPDataRetrieve(this, makeFileName(data, false)));
			}
			else
			{
				response(550);
			}
		}
		else if (cmd == "STOR")
		{
			createDataConnection(new FTPDataStore(this, makeFileName(data, true)));
		}
		else if (cmd == "LIST")
		{
			createDataConnection(new FTPDataFileList(this));
		}
		else if (cmd == "PASV")
		{
			response(500 , "Passive mode not supported");
		}
		else if (cmd == "NOOP")
		{
			response(200);
		}
		else if (!server->onCommand(cmd, data, *this))
			response(502, "Not supported");

		return;
	}

	debugf("!!!CASE NOT IMPLEMENTED?!!!");
}
Example #30
0
/*For simplicity the configuration setting code uses four characters for each configuration choice. This makes things easier for
 comparison purposes.
 */
void SerialConsole::handleConfigCmd() {
	PotThrottleConfiguration *acceleratorConfig = NULL;
	PotThrottleConfiguration *brakeConfig = NULL;
	MotorControllerConfiguration *motorConfig = NULL;
	Throttle *accelerator = DeviceManager::getInstance()->getAccelerator();
	Throttle *brake = DeviceManager::getInstance()->getBrake();
	MotorController *motorController = DeviceManager::getInstance()->getMotorController();
	int i;
	int newValue;
	bool updateWifi = true;

	//Logger::debug("Cmd size: %i", ptrBuffer);
	if (ptrBuffer < 6)
		return; //4 digit command, =, value is at least 6 characters
	cmdBuffer[ptrBuffer] = 0; //make sure to null terminate
	String cmdString = String();
	unsigned char whichEntry = '0';
	i = 0;

	while (cmdBuffer[i] != '=' && i < ptrBuffer) {
	 cmdString.concat(String(cmdBuffer[i++]));
	}
	i++; //skip the =
	if (i >= ptrBuffer)
	{
		Logger::console("Command needs a value..ie TORQ=3000");
		Logger::console("");
		return; //or, we could use this to display the parameter instead of setting
	}

	if (accelerator)
		acceleratorConfig = (PotThrottleConfiguration *) accelerator->getConfiguration();
	if (brake)
		brakeConfig = (PotThrottleConfiguration *) brake->getConfiguration();
	if (motorController)
		motorConfig = (MotorControllerConfiguration *) motorController->getConfiguration();

	// strtol() is able to parse also hex values (e.g. a string "0xCAFE"), useful for enable/disable by device id
	newValue = strtol((char *) (cmdBuffer + i), NULL, 0);

	cmdString.toUpperCase();
	if (cmdString == String("TORQ") && motorConfig) {
		Logger::console("Setting Torque Limit to %i", newValue);
		motorConfig->torqueMax = newValue;
		motorController->saveConfiguration();
	} else if (cmdString == String("RPM") && motorConfig) {
		Logger::console("Setting RPM Limit to %i", newValue);
		motorConfig->speedMax = newValue;
		motorController->saveConfiguration();
	} else if (cmdString == String("REVLIM") && motorConfig) {
		Logger::console("Setting Reverse Limit to %i", newValue);
		motorConfig->reversePercent = newValue;
		motorController->saveConfiguration();
	} else if (cmdString == String("TPOT") && acceleratorConfig) {
		Logger::console("Setting # of Throttle Pots to %i", newValue);
		acceleratorConfig->numberPotMeters = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("TTYPE") && acceleratorConfig) {
		Logger::console("Setting Throttle Subtype to %i", newValue);
		acceleratorConfig->throttleSubType = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("T1ADC") && acceleratorConfig) {
		Logger::console("Setting Throttle1 ADC pin to %i", newValue);
		acceleratorConfig->AdcPin1 = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("T1MN") && acceleratorConfig) {
		Logger::console("Setting Throttle1 Min to %i", newValue);
		acceleratorConfig->minimumLevel1 = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("T1MX") && acceleratorConfig) {
		Logger::console("Setting Throttle1 Max to %i", newValue);
		acceleratorConfig->maximumLevel1 = newValue;
		accelerator->saveConfiguration();
	}
	else if (cmdString == String("T2ADC") && acceleratorConfig) {
		Logger::console("Setting Throttle2 ADC pin to %i", newValue);
		acceleratorConfig->AdcPin2 = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("T2MN") && acceleratorConfig) {
		Logger::console("Setting Throttle2 Min to %i", newValue);
		acceleratorConfig->minimumLevel2 = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("T2MX") && acceleratorConfig) {
		Logger::console("Setting Throttle2 Max to %i", newValue);
		acceleratorConfig->maximumLevel2 = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("TRGNMAX") && acceleratorConfig) {
		Logger::console("Setting Throttle Regen maximum to %i", newValue);
		acceleratorConfig->positionRegenMaximum = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("TRGNMIN") && acceleratorConfig) {
		Logger::console("Setting Throttle Regen minimum to %i", newValue);
		acceleratorConfig->positionRegenMinimum = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("TFWD") && acceleratorConfig) {
		Logger::console("Setting Throttle Forward Start to %i", newValue);
		acceleratorConfig->positionForwardMotionStart = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("TMAP") && acceleratorConfig) {
		Logger::console("Setting Throttle MAP Point to %i", newValue);
		acceleratorConfig->positionHalfPower = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("TMINRN") && acceleratorConfig) {
		Logger::console("Setting Throttle Regen Minimum Strength to %i", newValue);
		acceleratorConfig->minimumRegen = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("TMAXRN") && acceleratorConfig) {
		Logger::console("Setting Throttle Regen Maximum Strength to %i", newValue);
		acceleratorConfig->maximumRegen = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("TCREEP") && acceleratorConfig) {
		Logger::console("Setting Throttle Creep Strength to %i", newValue);
		acceleratorConfig->creep = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("BMAXR") && brakeConfig) {
		Logger::console("Setting Max Brake Regen to %i", newValue);
		brakeConfig->maximumRegen = newValue;
		brake->saveConfiguration();
	} else if (cmdString == String("BMINR") && brakeConfig) {
		Logger::console("Setting Min Brake Regen to %i", newValue);
		brakeConfig->minimumRegen = newValue;
		brake->saveConfiguration();
	}
	else if (cmdString == String("B1ADC") && acceleratorConfig) {
		Logger::console("Setting Brake ADC pin to %i", newValue);
		brakeConfig->AdcPin1 = newValue;
		accelerator->saveConfiguration();
	} else if (cmdString == String("B1MX") && brakeConfig) {
		Logger::console("Setting Brake Max to %i", newValue);
		brakeConfig->maximumLevel1 = newValue;
		brake->saveConfiguration();
	} else if (cmdString == String("B1MN") && brakeConfig) {
		Logger::console("Setting Brake Min to %i", newValue);
		brakeConfig->minimumLevel1 = newValue;
		brake->saveConfiguration();
	} else if (cmdString == String("PREC") && motorConfig) {
		Logger::console("Setting Precharge Capacitance to %i", newValue);
		motorConfig->kilowattHrs = newValue;
		motorController->saveConfiguration();
	} else if (cmdString == String("PREDELAY") && motorConfig) {
		Logger::console("Setting Precharge Time Delay to %i milliseconds", newValue);
		motorConfig->prechargeR = newValue;
		motorController->saveConfiguration();
	} else if (cmdString == String("NOMV") && motorConfig) {
		Logger::console("Setting fully charged voltage to %d vdc", newValue);
		motorConfig->nominalVolt = newValue * 10;
		motorController->saveConfiguration();
        } else if (cmdString == String("BRAKELT") && motorConfig) {
		motorConfig->brakeLight = newValue;
		motorController->saveConfiguration();
		Logger::console("Brake light output set to DOUT%i.",newValue);
 } else if (cmdString == String("REVLT") && motorConfig) {
		motorConfig->revLight = newValue;
		motorController->saveConfiguration();
		Logger::console("Reverse light output set to DOUT%i.",newValue);
 } else if (cmdString == String("ENABLEIN") && motorConfig) {
		motorConfig->enableIn = newValue;
		motorController->saveConfiguration();
		Logger::console("Motor Enable input set to DIN%i.",newValue);
 } else if (cmdString == String("REVIN") && motorConfig) {
		motorConfig->reverseIn = newValue;
		motorController->saveConfiguration();
		Logger::console("Motor Reverse input set to DIN%i.",newValue);
	} else if (cmdString == String("MRELAY") && motorConfig) {
		Logger::console("Setting Main Contactor relay output to DOUT%i", newValue);
		motorConfig->mainContactorRelay = newValue;
		motorController->saveConfiguration();
	} else if (cmdString == String("PRELAY") && motorConfig) {
		Logger::console("Setting Precharge Relay output to DOUT%i", newValue);
		motorConfig->prechargeRelay = newValue;
		motorController->saveConfiguration();
	} else if (cmdString == String("ENABLE")) {
		if (PrefHandler::setDeviceStatus(newValue, true)) {
			sysPrefs->forceCacheWrite(); //just in case someone takes us literally and power cycles quickly
			Logger::console("Successfully enabled device.(%X, %d) Power cycle to activate.", newValue, newValue);
		}
		else {
			Logger::console("Invalid device ID (%X, %d)", newValue, newValue);
		}
	} else if (cmdString == String("DISABLE")) {
		if (PrefHandler::setDeviceStatus(newValue, false)) {
			sysPrefs->forceCacheWrite(); //just in case someone takes us literally and power cycles quickly
			Logger::console("Successfully disabled device. Power cycle to deactivate.");
		}
		else {
			Logger::console("Invalid device ID (%X, %d)", newValue, newValue);
		}
	} else if (cmdString == String("SYSTYPE")) {
		if (newValue < 5 && newValue > 0) {
			sysPrefs->write(EESYS_SYSTEM_TYPE, (uint8_t)(newValue));
			sysPrefs->saveChecksum();
			sysPrefs->forceCacheWrite(); //just in case someone takes us literally and power cycles quickly
			Logger::console("System type updated. Power cycle to apply.");
		}
		else Logger::console("Invalid system type. Please enter a value 1 - 4");

       
	} else if (cmdString == String("LOGLEVEL")) {
		switch (newValue) {
		case 0:
			Logger::setLoglevel(Logger::Debug);
			Logger::console("setting loglevel to 'debug'");
			break;
		case 1:
			Logger::setLoglevel(Logger::Info);
			Logger::console("setting loglevel to 'info'");
			break;
		case 2:
			Logger::console("setting loglevel to 'warning'");
			Logger::setLoglevel(Logger::Warn);
			break;
		case 3:
			Logger::console("setting loglevel to 'error'");
			Logger::setLoglevel(Logger::Error);
			break;
		case 4:
			Logger::console("setting loglevel to 'off'");
			Logger::setLoglevel(Logger::Off);
			break;
		}
		sysPrefs->write(EESYS_LOG_LEVEL, (uint8_t)newValue);
		sysPrefs->saveChecksum();

	} else if (cmdString == String("WIREACH")) {
		DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)(cmdBuffer + i));
		Logger::info("sent \"AT+i%s\" to WiReach wireless LAN device", (cmdBuffer + i));
                DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DOWN");	
		updateWifi = false;
	} else if (cmdString == String("SSID")) {
		String cmdString = String();
    	        cmdString.concat("WLSI");
   		cmdString.concat('=');
		cmdString.concat((char *)(cmdBuffer + i));
                Logger::info("Sent \"%s\" to WiReach wireless LAN device", (cmdString.c_str()));
       		DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)cmdString.c_str());
                DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DOWN");	
		updateWifi = false;
        } else if (cmdString == String("IP")) {
		String cmdString = String();
    	        cmdString.concat("DIP");
   		cmdString.concat('=');
		cmdString.concat((char *)(cmdBuffer + i));
                Logger::info("Sent \"%s\" to WiReach wireless LAN device", (cmdString.c_str()));
       		DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)cmdString.c_str());
                DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DOWN");	
		updateWifi = false;
 } else if (cmdString == String("CHANNEL")) {
		String cmdString = String();
    	        cmdString.concat("WLCH");
   		cmdString.concat('=');
		cmdString.concat((char *)(cmdBuffer + i));
                Logger::info("Sent \"%s\" to WiReach wireless LAN device", (cmdString.c_str()));
       		DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)cmdString.c_str());
                DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DOWN");	
		updateWifi = false;
	} else if (cmdString == String("SECURITY")) {
		String cmdString = String();
    	        cmdString.concat("WLPP");
   		cmdString.concat('=');
		cmdString.concat((char *)(cmdBuffer + i));
                Logger::info("Sent \"%s\" to WiReach wireless LAN device", (cmdString.c_str()));
       		DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)cmdString.c_str());
                DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DOWN");	
		updateWifi = false;
	
   } else if (cmdString == String("PWD")) {
		String cmdString = String();
    	        cmdString.concat("WPWD");
   		cmdString.concat('=');
		cmdString.concat((char *)(cmdBuffer + i));
                Logger::info("Sent \"%s\" to WiReach wireless LAN device", (cmdString.c_str()));
       		DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)cmdString.c_str());
                DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DOWN");	
		updateWifi = false;
	
	} else if (cmdString == String("COOLFAN") && motorConfig) {		
		Logger::console("Cooling fan output updated to: %i", newValue);
        motorConfig->coolFan = newValue;
		motorController->saveConfiguration();
	} else if (cmdString == String("COOLON")&& motorConfig) {
		if (newValue <= 200 && newValue >= 0) {
			Logger::console("Cooling fan ON temperature updated to: %i degrees", newValue);
			motorConfig->coolOn = newValue;
			motorController->saveConfiguration();
		}
		else Logger::console("Invalid cooling ON temperature. Please enter a value 0 - 200F");
	} else if (cmdString == String("COOLOFF")&& motorConfig) {
		if (newValue <= 200 && newValue >= 0) {
			Logger::console("Cooling fan OFF temperature updated to: %i degrees", newValue);
			motorConfig->coolOff = newValue;
			motorController->saveConfiguration();
	    }
		else Logger::console("Invalid cooling OFF temperature. Please enter a value 0 - 200F");
	} else if (cmdString == String("OUTPUT") && newValue<8) {
                int outie = getOutput(newValue);
                Logger::console("DOUT%d,  STATE: %d",newValue, outie);
                if(outie)
                  {
                    setOutput(newValue,0);
                    motorController->statusBitfield1 &= ~(1 << newValue);//Clear
                  }
                   else
                     {
                       setOutput(newValue,1);
                        motorController->statusBitfield1 |=1 << newValue;//setbit to Turn on annunciator
		      }
                  
             
        Logger::console("DOUT0:%d, DOUT1:%d, DOUT2:%d, DOUT3:%d, DOUT4:%d, DOUT5:%d, DOUT6:%d, DOUT7:%d", getOutput(0), getOutput(1), getOutput(2), getOutput(3), getOutput(4), getOutput(5), getOutput(6), getOutput(7));
	} else if (cmdString == String("NUKE")) {
		if (newValue == 1) 
		{   //write zero to the checksum location of every device in the table.
			//Logger::console("Start of EEPROM Nuke");
			uint8_t zeroVal = 0;
			for (int j = 0; j < 64; j++) 
			{
				memCache->Write(EE_DEVICES_BASE + (EE_DEVICE_SIZE * j), zeroVal);
				memCache->FlushAllPages();
			}			
			Logger::console("Device settings have been nuked. Reboot to reload default settings");
		}
	} else {
		Logger::console("Unknown command");
		updateWifi = false;
	}
	// send updates to ichip wifi
	if (updateWifi)
		DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_CONFIG_CHANGE, NULL);
}