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(); }
// 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; }
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; }
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); }
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 }
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())); } }
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; }