예제 #1
0
RundGangApp::RundGangApp(bb::cascades::Application *app) :
        QObject(app)
{
    // Localization: Make the initial call to set up the initial application language and
    // connect to the LocaleHandlers systemLanguaged change signal, this will
    // tell the application when it is time to load a new set of language strings.
    mTranslator = new QTranslator(this);
    mLocaleHandler = new LocaleHandler(this);
    onSystemLanguageChanged();
    bool connectResult = connect(mLocaleHandler, SIGNAL(systemLanguageChanged()), SLOT(onSystemLanguageChanged()));
    Q_ASSERT(connectResult);
    Q_UNUSED(connectResult);

    // Register objects for assisting the Control of the Photo feedback page.
    qmlRegisterType<PhotoController>("com.rundgang", 1, 0, "PhotosController");
    qmlRegisterType<AudioController>("com.rundgang", 1, 0, "AudioController");
    qmlRegisterType<CustomSqlDataSource>("com.rundgang", 1, 0, "CustomSqlDataSource");
    qmlRegisterType<EmailController>("com.rundgang", 1, 0, "EmailController");

    // Registering picker types and Contact Picker helper object,
    // so that it can be used in QML.
    qmlRegisterType<ContactPicker>("bb.cascades.pickers", 1, 0, "ContactPicker");
    qmlRegisterUncreatableType<ContactSelectionMode>("bb.cascades.pickers", 1, 0,
            "ContactSelectionMode", "Non creatable enum type");

    // Create scene document from main.qml asset, the parent is set
    // to ensure the document gets destroyed properly at shut down.
    QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);

    // Create the GlobalSettings object that holds application wide settings.
    GlobalSettings *globalSettings = new GlobalSettings(this);
    qml->setContextProperty("_appSettings", globalSettings);

    // Make the application object accessible from QML.
    qml->setContextProperty("_app", this);

    // Set the stored visual style of the application.
    app->themeSupport()->setVisualStyle(globalSettings->visualStyle());

    // Create root object for the UI.
    AbstractPane *root = qml->createRootObject<AbstractPane>();

    // Set created root object as the application scene.
    app->setScene(root);

    // Add an application cover, shown when the app is running in minimized mode.
    addApplicationCover();
}
예제 #2
0
// Returns a new filename using the timestamp: img_YYYYMMDD_HHMMSSuuu.
// Verifies if a file already exists with the generated filename, if it does we increment the filename.
CString GenerateAutoFileName()
{
    GlobalSettings gs;
    CString timeStr;
    CString path;
    SYSTEMTIME tNow;
    CString ext;  
      
    path = gs.bAutoName ? gs.getOutputDir() : _T("\\");
    GetLocalTime(&tNow);
    timeStr.Format(_T("img_%u%02u%02u_%02u%02u%02u%03u"), tNow.wYear, tNow.wMonth, tNow.wDay, tNow.wHour, tNow.wMinute, tNow.wSecond, tNow.wMilliseconds);

    // We check which encoder is selected to know what extension to use
    switch (gs.sEnc)
    {
        case sEncBMP:
            ext = _T(".bmp");
            break;
            
        case sEncJPEG:
            ext = _T(".jpg");
            break;
            
        case sEncPNG:
            ext = _T(".png");
            break;
            
        default:
            ext = _T("");
            break;
    }
    
    // Check if the file already exists
    while( CheckFileExists(path + timeStr + ext) )
    {
        if (tNow.wMilliseconds == 999)
        {
            break;
        }
        else
        {    
            tNow.wMilliseconds += 1;
            timeStr.Format(_T("img_%u%02u%02u_%02u%02u%02u%03u"), tNow.wYear, tNow.wMonth, tNow.wDay, tNow.wHour, tNow.wMinute, tNow.wSecond, tNow.wMilliseconds);
        }
    }
    return timeStr + ext;
}
예제 #3
0
파일: main.cpp 프로젝트: frispete/mp3diags
string getActiveSession(const po::variables_map& options, int& nSessCnt, bool& bOpenLast, string& strTempSessTempl, string& strDirSessTempl)
{
    string strRes;
    vector<string> vstrSess;
    //string strLast;
    GlobalSettings st;
    string strTranslation;

    st.loadSessions(vstrSess, strRes, bOpenLast, strTempSessTempl, strDirSessTempl, strTranslation);
    nSessCnt = cSize(vstrSess);

    if (options.count(s_sessionOpt.m_szLongOpt) > 0)
    {
        strRes = options[s_sessionOpt.m_szLongOpt].as<string>();
    }

    return strRes;
}
예제 #4
0
void Logging::init()
{
	GlobalSettings settings;

	buffer_size_ =
		settings.value(GlobalSettings::Key_Log_BufferSize).toInt();

	buffer_.reserve(buffer_size_);

	qInstallMessageHandler(log_pv);
	sr_log_callback_get(&prev_sr_log_cb, &prev_sr_log_cb_data);
	sr_log_callback_set(log_sr, nullptr);
#ifdef ENABLE_DECODE
	srd_log_callback_get(&prev_srd_log_cb, &prev_srd_log_cb_data);
	srd_log_callback_set(log_srd, nullptr);
#endif

	GlobalSettings::add_change_handler(this);
}
예제 #5
0
QString FileDialog::getSaveFileName(
    QWidget *parent,
    const QString &caption,
    const QString &dir,
    const QString &filter,
    const GlobalSettings &settings)
{
#if defined(OWN_FILE_DIALOG)
    return OwnFileDialog::ExecuteFileDialog(
        OwnFileDialog::Type_SaveFile, parent, caption, dir, filter, settings);
#else
    NativeFileDialog nfd(QFileDialog::AcceptSave, parent, caption, dir, filter, settings.GetLimitDir());
    return 0 == nfd.exec() ? "" : nfd.selectedFiles()[0];
#endif
}
예제 #6
0
int main(int argc, char** argv)
{
    QGuiApplication app(argc, argv);
    app.setApplicationName("sasquatch");
    app.setOrganizationName("MediaTrolls");
    app.setOrganizationDomain("sasquatch.com");

    GlobalSettings *settings = new GlobalSettings(&app);

    if (app.arguments().contains("--help") || app.arguments().contains("-help") || app.arguments().contains("-h")) {
        printf("Usage: sasquatch [-option value] [-option=value]\n"
               "\n"
               "Options (default):\n");

        for (int i = 0; i < GlobalSettings::OptionLength; ++i) {
            printf("  -%-20s %s \t (%s)\n",
                   qPrintable(settings->name((GlobalSettings::Option)i)),
                   qPrintable(settings->doc((GlobalSettings::Option)i)),
                   qPrintable(settings->value((GlobalSettings::Option)i).toString()));
        }

        printf("\n");

        // try to print skin specific settings
        settings->parseArguments(app.arguments());

        SkinManager *skinManager = new SkinManager(settings);
        if (skinManager->skins().contains(settings->value(GlobalSettings::Skin).toString())) {
            Skin *skin = skinManager->skins().value(settings->value(GlobalSettings::Skin).toString());
            if (!skin->parseManifest())
                return 1;

            printf("\n"
                   "Skin '%s' Options (default):\n", qPrintable(skin->name()));

            Settings *skinSettings = skin->settings();
            foreach (const QString &key, skinSettings->keys()) {
                printf("  -%-20s %s \t (%s)\n",
                       qPrintable(key),
                       qPrintable(skinSettings->doc(key)),
                       qPrintable(skinSettings->value(key).toString()));
            }
        }
예제 #7
0
파일: main.cpp 프로젝트: frispete/mp3diags
int guiMain(const po::variables_map& options) {

    { // by default on Windows the selection is hard to see in the main window, because it's some gray;
        QPalette pal (QApplication::palette());
        pal.setColor(QPalette::Highlight, pal.color(QPalette::Active, QPalette::Highlight));
        pal.setColor(QPalette::HighlightedText, pal.color(QPalette::Active, QPalette::HighlightedText));
        QApplication::setPalette(pal);
    }

    getDefaultFont(); // !!! to initialize the static var

    string strStartSession;
    string strLastSession;

    int nSessCnt;
    bool bOpenLast;
    string strTempSessTempl;
    string strDirSessTempl;
    //bool bIsTempSess (false);
    string strTempSession (getSepTerminatedDir(convStr(QDir::tempPath())) + TEMP_SESS + SessionEditorDlgImpl::SESS_EXT);
    string strFolderSess;
    bool bHideFolderSess (true);

    if (options.count(s_hiddenFolderSessOpt.m_szLongOpt) > 0)
    {
        strFolderSess = options[s_hiddenFolderSessOpt.m_szLongOpt].as<string>();
    }
    else if (options.count(s_loadedFolderSessOpt.m_szLongOpt) > 0)
    {
        strFolderSess = options[s_loadedFolderSessOpt.m_szLongOpt].as<string>();
        bHideFolderSess = false;
    }

    SessEraser sessEraser;

    strLastSession = getActiveSession(options, nSessCnt, bOpenLast, strTempSessTempl, strDirSessTempl);

    if (options.count(s_tempSessOpt.m_szLongOpt) > 0)
    {
        SessEraser::eraseTempSess();

        strStartSession = strTempSession;

        if (strTempSessTempl.empty())
        {
            strTempSessTempl = strLastSession;
        }

        if (!strTempSessTempl.empty())
        {
            try
            {
                copyFile2(strTempSessTempl, strStartSession);
            }
            catch (...)
            { // nothing //ttt2 do more
            }
        }

        string strProcDir (options[s_tempSessOpt.m_szLongOpt].as<string>());
        strProcDir = getNonSepTerminatedDir(convStr(QDir(fromNativeSeparators(convStr(strProcDir))).absolutePath()));
        setFolder(strStartSession, strProcDir);
        bOpenLast = true;
    }
    else if (!strFolderSess.empty())
    {
        string strProcDir = getNonSepTerminatedDir(convStr(QDir(fromNativeSeparators(convStr(strFolderSess))).absolutePath())); //ttt2 test on root

        if (!dirExists(strProcDir))
        {
            showMessage(0, QMessageBox::Critical, 0, 0, MainFormDlgImpl::tr("Error"), MainFormDlgImpl::tr("Folder \"%1\" doesn't exist. The program will exit ...").arg(convStr(strProcDir)), MainFormDlgImpl::tr("O&K"));
            return 1;
        }

        string strDirName (convStr(QFileInfo(convStr(strProcDir)).fileName()));
        if (strDirName.empty()) // it's a whole disk drive on Windows, e.g. D:\\  ;
        {
            strDirName += strProcDir[0];
            strDirName += "-MP3Diags";
        }
        strStartSession = getSepTerminatedDir(strProcDir) + strDirName + SessionEditorDlgImpl::SESS_EXT;
        if (bHideFolderSess)
        {
            sessEraser.m_strSessionToHide = strStartSession;
        }

        if (!fileExists(strStartSession))
        {
            if (strDirSessTempl.empty())
            {
                strDirSessTempl = strLastSession;
            }

            if (!strDirSessTempl.empty())
            {
                try
                {
                    copyFile2(strDirSessTempl, strStartSession);
                    setFolder(strStartSession, strProcDir);
                }
                catch (...)
                { // nothing //ttt2 do more
                }
            }
        }

        ofstream out (strStartSession.c_str(), ios_base::app);
        if (!out)
        {
            showMessage(0, QMessageBox::Critical, 0, 0, MainFormDlgImpl::tr("Error"), MainFormDlgImpl::tr("Cannot write to file \"%1\". The program will exit ...").arg(convStr(strStartSession)), MainFormDlgImpl::tr("O&K"));
            return 1;
        }
        bOpenLast = true;
    }
    else if (0 == nSessCnt)
    { // first run; create a new session and run it
        SessionEditorDlgImpl dlg (0, "", SessionEditorDlgImpl::FIRST_TIME, ""); // ttt0 detect system locale
        dlg.setWindowIcon(QIcon(":/images/logo.svg"));
        strStartSession = dlg.run();
        if (strStartSession.empty())
        {
            return 0;
        }

        if ("*" == strStartSession)
        {
            strStartSession.clear();
        }
        else
        {
            vector<string> vstrSess;
            //vstrSess.push_back(strStartSession);
            GlobalSettings st;
            st.saveSessions(vstrSess, strStartSession, dlg.shouldOpenLastSession(), "", "", dlg.getTranslation(), GlobalSettings::LOAD_EXTERNAL_CHANGES);
        }
        bOpenLast = true;
    }
    else
    {
        strStartSession = strLastSession;
    }

    bool bOpenSelDlg (strStartSession.empty() || !bOpenLast);

    try
    {
        for (;;)
        {
            {
                QFont fnt;
                string strNewFont (convStr(fnt.family()));
                int nNewSize (fnt.pointSize());
                fixAppFont(fnt, strNewFont, nNewSize);
            }

            if (bOpenSelDlg)
            {
                SessionsDlgImpl dlg (0);
                dlg.setWindowIcon(QIcon(":/images/logo.svg"));

                strStartSession = dlg.run();
                if (strStartSession.empty())
                {
                    return 0;
                }
            }
            bOpenSelDlg = true;

            CB_ASSERT (!strStartSession.empty());

            bool bDefaultForVisibleSessBtn (true);
            //if (strStartSession != strTempSession)
            {
                vector<string> vstrSess;
                bool bOpenLast;
                string s, s1, s2, s3;
                GlobalSettings st;
                st.loadSessions(vstrSess, s, bOpenLast, s1, s2, s3);
                st.saveSessions(vstrSess, strStartSession, bOpenLast, s1, s2, s3, GlobalSettings::LOAD_EXTERNAL_CHANGES);
                bDefaultForVisibleSessBtn = (cSize(vstrSess) != 1 || !strFolderSess.empty() || vstrSess.end() != find(vstrSess.begin(), vstrSess.end(), strTempSession));
            }

            { //ttt2 overkill - create a "CommonData" just to read the language setting
                SessionSettings settings (strStartSession);
                CommonData commonData(settings, 0, 0, 0, 0, 0, 0, 0, 0, 0, false);
                settings.loadMiscConfigSettings(&commonData, SessionSettings::DONT_INIT_GUI);
                TranslatorHandler::getGlobalTranslator().setTranslation(commonData.m_strTranslation); // !!! must be done here, before the MainFormDlgImpl constructor
            }

            MainFormDlgImpl mainDlg (strStartSession, bDefaultForVisibleSessBtn);
            mainDlg.setWindowIcon(QIcon(":/images/logo.svg"));

            if (bDefaultForVisibleSessBtn)
            {
                mainDlg.setWindowTitle(QString(getAppName()) + " - " + convStr(SessionEditorDlgImpl::getTitleName(strStartSession)));
            }
            else
            {
                mainDlg.setWindowTitle(QString(getAppName()));
            }

            if (MainFormDlgImpl::OPEN_SESS_DLG != mainDlg.run())
            {
                return 0;
            }
        }
    }
    catch (const exception& ex)
    {
        CB_ASSERT1 (false, ex.what());
    }
    catch (...) // ttt2 for now it doesn't catch many exceptions; it seems that nothing can be done if an exception leaves a slot / event handler, but maybe there are ways around
    {
        /*QMessageBox dlg (QMessageBox::Critical, "Error", "Caught generic exception. Exiting ...", QMessageBox::Close, 0, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint);

        dlg.exec();
        qDebug("out - err");*/
        CB_ASSERT (false);
    }

    /*mainDlg.show();
    return app.exec();*/
}
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;
}