Страница 1 из 2 12 ПоследняяПоследняя
Показано с 1 по 10 из 12

Тема: Проблема с sysExecute5

  1. #1

    По умолчанию Проблема с sysExecute5

    Коллеги, добрый день. Случилась такая вот проблема. Перестал работать парсинг JSON через ФБ sysExecute5. Хотел добавить пару изменений, разобрался с проблемой кириллицы (для тех, кто вдруг столкнется с этой проблемой: jq в любом случае выводит строку в кодировке UTF-8 в терминал, в cds 3.5.7.30 string имеет кодировку ascii, wstring - UCS-2, по этой причине в string вы не сможете записать кириллицу, а для wstring вам надо будет перекодировать строку с помощью iconv в UTF-16 сразу, либо другими способами, из библиотеки owen string utils функция CP1251_TO_UNICODE у меня не сработала), но не могу этого проверить тк вывода по сути нету. Из изменений в коде считай никаких, только изменение самой команды, отправляемой в терминал, изменения размера массива, в который потом данные записываются (добавилось 9 сигналов), изменился тип массива выходных данных (со string на wstring), и файл конфига новый (название файла поменял). В чем проблема: при старте программы ФБ sysExecute5 встает в положение xExecute := true, но после xBusy остается false и не меняет своего значения. Откат к предыдущей версии тоже перестал работать.
    Код программы ниже (упрощенная версия тк пытался сам понять, в чем проблема, тут только запись в буфер данных, без их распределения, поведение одинаковое в обоих случаях):
    Код:
    PROGRAM INICIATE_SIGNALS_2
    VAR
      GetDataFromJSON: BOOL := TRUE;
      sPathToFile:   STRING := 'home/root/CODESYS/cfg_2.json';
      fbJSONParser:  CmpSysExec.sysExecute5;
      sCommand:     STRING(255);
      i:         INT := 0;
      wsDITemp:     ARRAY [0..c_iDISize] OF WSTRING(512);
      wsDOTemp:     ARRAY [0..c_iDOSize] OF WSTRING(512);
      wsIDOTemp:     ARRAY [0..c_iIDOSize] OF WSTRING(512);
      wsAITemp:     ARRAY [0..c_iAISize] OF WSTRING(512);
      wsTIMERSTemp:   ARRAY [0..c_iTimersSize] OF WSTRING(512);
      eJSONFIeld:    JSON_FIELD := JSON_FIELD.discret_inputs; 
    END_VAR
    VAR CONSTANT
      c_iDISize:    INT := 264;
      c_iDOSize:     INT := 146;
      c_iIDOSize:    INT := 141;
      c_iAISize:    INT := 40;
      c_iTimersSize:  INT := 21;
      c_sCommand:    STRING(255) := 'jq -c $'.#SIGNALS#[] $' #PATH_TO_FILE# | iconv -f UTF-8 -t UTF-16BE';
      //c_sCommand:    STRING(255) := 'jq -c $'.#SIGNALS#[] $' #PATH_TO_FILE#'; 
    END_VAR
    
    IF GetDataFromJSON THEN
      CASE eJSONFIeld OF
        JSON_FIELD.discret_inputs:
          
          sCommand := OSU.ReplaceSubstring(sSource := c_sCommand,
                          sWhatToReplace := '#SIGNALS#',
                          sReplaceWith := 'di_signals');
                          
          sCommand := OSU.ReplaceSubstring(sSource := sCommand,
                          sWhatToReplace := '#PATH_TO_FILE#',
                          sReplaceWith := sPathToFile);
          
          fbJSONParser(xExecute := TRUE,
            pCommand := ADR(sCommand),
            szCommand := SIZEOF(sCommand),
            pOutput := ADR(wsDITemp[i]),
            szOutput := SIZEOF(wsDITemp[i])
          );
          
          IF fbJSONParser.xBusy AND wsDITemp[i] <> "" AND i < c_iDISize THEN
            i := i+1;
          END_IF
          
          IF fbJSONParser.xDone THEN
            fbJSONParser(xExecute := FALSE);
            i := 0;
            eJSONFIeld := JSON_FIELD.NULL;
          END_IF
        JSON_FIELD.NULL:
          PLC_SIGNALS.init_to_spk := TRUE;
          GetDataFromJSON := FALSE;
      END_CASE
    END_IF
    Последний раз редактировалось Dmitry Dedkov; 10.06.2025 в 11:29.

  2. #2
    Супер Модератор Аватар для Евгений Кислов
    Регистрация
    27.01.2015
    Адрес
    Москва
    Сообщений
    13,597

    По умолчанию

    Добрый день.

    Навскидку

    Код:
    szCommand := SIZEOF(sCommand),
    Выглядит сомнительно. Логичнее было бы использовать LEN вместо SIZEOF.

    Но я не уверен, что это единственная причина наблюдаемого вами поведения.

    Лучше напишите на support@owen.ru и приложите к письму ссылку на наиболее простую версию вашего проекта, в которой удается повторить данную проблему.

    Откат к предыдущей версии тоже перестал работать.
    Если вы делали это без перезагрузки ПЛК - это логично. При некорректном использовании SysExecute начинаются проблемы с содержимым оперативной памяти.

  3. #3

    По умолчанию

    Мой код по отправке почты через CmpSysExec.SysExecute5
    Всё давно работает, ничего не ломается
    Кириллица поддержана
    Вдруг поможет

    Код:
    //Файл '/home/SendMail.txt' должен выглядеть как-то так:
    (*-------------------------------------------------------------------------------------------------------------------
    From: fff@ggggg.ru
    To: ggggn@hhhhh.ru, hgjhgj@hgjhgjhgj.ru
    Subject: Тема письма
    MIME-Version: 1.0
    Content-Type: multipart/mixed; boundary="BOUNDARY"
    
    --BOUNDARY
    Content-Type: text/plain; charset=UTF-8
    
    Здесь идёт текстовка самого письма, строка №1
    Здесь идёт текстовка самого письма, строка №2
    
    --BOUNDARY
    Content-Type: text/plain; charset=UTF-8
    Content-Disposition: attachment; filename*=UTF-8''%D1%84%D0%B0%D0%B9%D0%BB.txt
    Content-Transfer-Encoding: UTF-8
    
    Здесь идёт текстовка вложенного файла, строка №1
    Здесь идёт текстовка вложенного файла, строка №2
    Здесь идёт текстовка вложенного файла, строка №3
    --BOUNDARY
    -------------------------------------------------------------------------------------------------------------------*)
    FUNCTION_BLOCK My_CURL_EMAIL (*ФБ отправки электронной почты*)
    
    //Входы-Выходы
    VAR_IN_OUT
    	xExecute : BOOL; //Запуск
    	Mutex    : BOOL; //Mutex для блокировки
    END_VAR
    
    //Входы
    VAR_INPUT
    	sMailTo      : WSTRING(255);    //Список получателей
    	sTopic       : WSTRING(255);    //Тема письма
    	sMessage     : WSTRING(131071); //Текстовка письма
    	sFileName    : WSTRING(255);    //Имя файла для вложения
    	sTextForFile : WSTRING(131071); //Содержимое файла для вложения
    END_VAR
    
    //Выходы
    VAR_OUTPUT
    	xDone  : BOOL; //Признак конца работы
    	xBusy  : BOOL; //Признак занятости
    	xError : BOOL; //Признак ошибки
    END_VAR
    
    //Внутренние параметры
    VAR
    	//R-триггер для фиксации запуска работы ФБ 
    	fbRiseEdge : R_TRIG;
    	
    	//Тексты для "/home/SendEmail.txt"
    	sMailFile      : WSTRING(131071); //Текст файла для отправки письма "/home/SendEmail.txt"
    	sMailFile_UTF8 : STRING(131071);  //Текст файла для отправки письма "/home/SendEmail.txt" в кодировке UTF8
    	
    	//ФБ для отправки команд на контроллерную консоль
    	fbSe5: CmpSysExec.SysExecute5;
    	
    	//Немножко магии для работы с файлом
    	pResult : POINTER TO SysFile.SysTypes.RTS_IEC_RESULT;
    	hFile   : POINTER TO SysFile.SysTypes.RTS_IEC_HANDLE;
    	
    	//Вспомогательный текст
    	TempText : WSTRING(1023);
    	
    	//Реальная команда отправки на контроллерную консоль
    	sCommand_Real: STRING(2047) := '';
    	
    	//Массив для парсинга списка получателей
    	MassivParsing        : ARRAY[1..255] OF WSTRING(255); //Сам массив
    	sCommandParsing      : WSTRING(255);                  //Итоговая строка
    	sCommandParsing_UTF8 : STRING(255);                   //Итоговая строка в UTF8
    	
    	//Ненужный ответ от блока отправки на консоль //Но удалять его нельзя, т.к., без него блок не работает
    	asOutput: STRING(2047);
    	
    	//Переменная цикла
    	i     : INT;  //Сама переменная
    	i_Max : DINT; //Максимальный индекс массива для парсинга списка получателей
    	
    	//Определение реального конца работы
    	Mutex_TON       : TON;  //Таймер
    	Mutex_TON_PrVkl : BOOL; //Признак активации таймера
    END_VAR
    
    //Константы
    VAR CONSTANT
    	//Команда отправки на контроллерную консоль
    	sCommand: STRING(2047) := 'curl --mail-from "qqq@qqq.ru" #MAILRCPT# --url "smtp://444.44.4.4:25" -u ggg@hhhh.ru:fdglfdmnjnfdlg --upload-file "/home/SendEmail.txt"';
    END_VAR
    Код:
    //Проверяем признак запуска
    fbRiseEdge(CLK := (xExecute AND NOT Mutex));
    
    //Если появился признак запуска...
    IF fbRiseEdge.Q THEN
    	
    	//Парсим список получателей
    	i_Max := OSU.WSplitStringByToken(ADR(sMailTo), TO_UINT(WLen(sMailTo)), ", ", ADR(MassivParsing), SIZEOF(MassivParsing[1]), 255); //Парсим строку
    	
    	//Цикл для формирования итоговой строки после парсинга списка получателей
    	sCommandParsing := "";
    	FOR i := 1 TO DINT_TO_INT(i_Max) DO
    		sCommandParsing := WCONCAT04(sCommandParsing, " --mail-rcpt $"", MassivParsing[i], "$"");
    	END_FOR
    	
    	//Итоговая строка после парсинга списка получателей в правильной кодировке UTF8
    	STU.ConvertUTF16toUTF8(ADR(sCommandParsing), ADR(sCommandParsing_UTF8), SIZEOF(sCommandParsing_UTF8), FALSE);
    	sCommand_Real := OSU.ReplaceSubstring(sCommand, '#MAILRCPT#', sCommandParsing_UTF8);
    
    	//Формируем текстовку письма, где будут лежать все его параметры
    	//Обнуляем
    	Memutils.MemSet (ADR(sMailFile),      0, SIZEOF(sMailFile));
    	Memutils.MemSet (ADR(sMailFile_UTF8), 0, SIZEOF(sMailFile_UTF8));
    	sMailFile := "";
    	sMailFile_UTF8 := '';
    	
    	//Пишем строки от кого и кому
    	TempText := WCONCAT03("From: opa@zaoshr.ru$r$nTo: ", sMailTo, "$r$nSubject: ");
    	SuperAddWString(ADR(sMailFile), ADR(TempText), TO_DWORD(SIZEOF(sMailFile)));
    	
    	//Тема письма
    	SuperAddWString(ADR(sMailFile), ADR(sTopic), TO_DWORD(SIZEOF(sMailFile)));
    	
    	//Пишем строки
    	TempText := "$r$nMIME-Version: 1.0$r$nContent-Type: multipart/mixed; boundary=$"BOUNDARY$"$r$n$r$n--BOUNDARY$r$nContent-Type: text/plain; charset=UTF-8$r$n$r$n";
    	SuperAddWString(ADR(sMailFile), ADR(TempText), TO_DWORD(SIZEOF(sMailFile)));
    	
    	//Текстовка письма
    	SuperAddWString(ADR(sMailFile), ADR(sMessage), TO_DWORD(SIZEOF(sMailFile)));
    	
    	//Пишем строки
    	TempText := "$r$n$r$n--BOUNDARY$r$nContent-Type: text/plain; charset=UTF-8$r$nContent-Disposition: attachment; filename*=UTF-8''";
    	SuperAddWString(ADR(sMailFile), ADR(TempText), TO_DWORD(SIZEOF(sMailFile)));
    	
    	//Имя файла в кодировке "URL Escape Codes"
    	TempText := Convert_To_URL_Escape_Code(sFileName);
    	SuperAddWString(ADR(sMailFile), ADR(TempText), TO_DWORD(SIZEOF(sMailFile)));
    	
    	//Пишем строки
    	TempText := "$r$nContent-Transfer-Encoding: UTF-8$r$n$r$n";
    	SuperAddWString(ADR(sMailFile), ADR(TempText), TO_DWORD(SIZEOF(sMailFile)));
    	
    	//Содержимое файла для вложения
    	SuperAddWString(ADR(sMailFile), ADR(sTextForFile), TO_DWORD(SIZEOF(sMailFile)));
    	
    	//Пишем строки
    	TempText := "$r$n--BOUNDARY";
    	SuperAddWString(ADR(sMailFile), ADR(TempText), TO_DWORD(SIZEOF(sMailFile)));
    	
    	//Конвертер в UTF8
    	STU.ConvertUTF16toUTF8(ADR(sMailFile), ADR(sMailFile_UTF8), TO_DWORD(SIZEOF(sMailFile_UTF8)), FALSE);
    	
    	//Пишем файл "/home/SendEmail.txt" перед отправкой самого письма	
    	hFile := SysFile.SysFileOpen('/home/SendEmail.txt', SysFile.ACCESS_MODE.AM_WRITE, pResult);
    	SysFile.SysFileWrite(hFile, ADR(sMailFile_UTF8), TO_UDINT(StrLenA(ADR(sMailFile_UTF8))), pResult); //Пишем
    	SysFile.SysFileClose(hFile);
    	
    	//Сброс команды запуска и активация блокировки по Mutex
    	xExecute        := FALSE;
    	Mutex           := TRUE;
    	Mutex_TON_PrVkl := TRUE;
    END_IF
    
    //Блок отправки команды через контроллерную консоль
    fbSe5
    (
    	xExecute  := fbRiseEdge.Q, 
    	pCommand  := ADR(sCommand_Real),
     	szCommand := TO_DWORD(STU.StrLenA(ADR(sCommand_Real))),
    	pOutput   := ADR(asOutput),    //Ненужный ответ //Но удалять его нельзя, т.к., без него блок не работает
    	szOutput  := SIZEOF(asOutput), //Ненужный ответ //Но удалять его нельзя, т.к., без него блок не работает
    	xDone     => xDone, 
    	xBusy     => xBusy, 
    	xError    => xError
    );
    
    //Таймер конца работы, проверка на разблокировку и сама разблокировка
    Mutex_TON(IN := Mutex_TON_PrVkl, PT := T#10S);
    IF Mutex_TON_PrVkl AND (xDone OR xError OR Mutex_TON.Q) THEN
    	Mutex_TON_PrVkl := FALSE;
    	Mutex           := FALSE;
    END_IF
    Последний раз редактировалось aaaSashaMGGU; 10.06.2025 в 16:45.

  4. #4

    По умолчанию

    По определенным причинам весь проект не смогу скинуть, только ту часть, которая затрагивает конкретно инициализацию из JSON файла. В целом то, что я уже продемонстрировал, является самой простой версией проекта, в которой у меня данная проблема возникла.
    При некорректном использовании SysExecute начинаются проблемы с содержимым оперативной памяти.
    Это я заметил давно, но забываю постоянно, когда прошлую версию инициализации делал

  5. #5

    По умолчанию

    Написал на почту, вчера уже никак не мог, не было под рукой проекта

  6. #6

    По умолчанию

    Я так и сделал, проблема сохранилась. Этот проект и отправил по почте в поддержку

  7. #7

    По умолчанию

    Файл отправил, команда в терминале выполняется без проблем. В Putty и при подключении по ssh из убунту все хорошо, но вот когда использую встроенный терминал в winscp результат как раз похож на тот, что дает вывод. На счет поврежден или нет попробую проверить.
    Снимок экрана от 2025-06-11 10-45-50.pngСнимок экрана от 2025-06-11 10-46-40.pngСнимок экрана от 2025-06-11 10-47-12.png

  8. #8

    По умолчанию

    А возможно ли такое, что у меня повредились системные библиотеки? А то у меня даже R_TRIG работает не корректно (попробовал вернуться к примеру из документа и при смене CLK := xExecute с false на true выход Q у триггера у меня не меняет своего значения)

  9. #9

    По умолчанию

    Цитата Сообщение от Dmitry Dedkov Посмотреть сообщение
    А возможно ли такое, что у меня повредились системные библиотеки? А то у меня даже R_TRIG работает не корректно (попробовал вернуться к примеру из документа и при смене CLK := xExecute с false на true выход Q у триггера у меня не меняет своего значения)
    Скорее всего у вас данная программа, без задачи, а значит не исполняется.
    Вы же ни одного скрина не дали и проект не выложили. А выход R_TRIG можно и не увидеть глазами, если что.
    А так же после изменений надо делать Очистить всё, компилировать всё, периодически.
    Последний раз редактировалось kondor3000; 11.06.2025 в 15:01.

  10. #10

    По умолчанию

    Программа добавлена в задачу MainTask, все она исполняется. У меня получилось получить код ошибки, но где его посмотреть (код ошибки 1). До этого его не выводило

Страница 1 из 2 12 ПоследняяПоследняя

Похожие темы

  1. Ответов: 4
    Последнее сообщение: 12.03.2025, 14:57

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •