Ad Widget

Collapse

Вывод в графе "Последнее значение" вместо кириллицы код

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Balbes
    Junior Member
    • Feb 2020
    • 7

    #1

    Вывод в графе "Последнее значение" вместо кириллицы код

    Доброго времени суток!
    Помогите найти решение: При получении данных с устройства (например принтер Brother) в графе "Последнее значение" страницы "Отчеты" - "Последние данные" выводится "C1 DF EF E9 D8 D9 20 E0 D5 D6 D8 DC". Ну и, в принципе, такое же везде, куда вывожу значения запроса. В то же самое время, если выполняю "snmpget -v 2c -c public -On ххх.ххх.ххх.ххх .1.3.6.1.2.1.43.18.1.1.8.1.1 > D:\zabbix\temp\11111.txt" - в выводе файла все на кириллице ".1.3.6.1.2.1.43.18.1.1.8.1.1 = STRING: "Спящий режим"". Если вывод делаю в коммандную строку - кракозябры ".1.3.6.1.2.1.43.18.1.1.8.1.1 = STRING: "БЯпйШЩ аХЦШЬ"".
    Как добиться, чтобы на страницах заббикса полученные данные отображались корректно? Понимаю, что вопрос в кодировке, но как решить - не пойму.
    На сервере (базе данных) используется кодировка UTF-8. Все страницы заббикса отображаются корректно на кириллице кроме этого вывода. В выводе текстового файла кодировка получается "Кириллица - ISO8859-5"
  • radix
    Administrator
    Zabbix Certified Specialist
    • Apr 2017
    • 6

    #2
    Your problem: Russian language not English configured on printer ;-)

    SNMP OID string output is in HEX not ASCII and encoding not UTF-8 but Latin/Cyrillic

    In shell it could be converted in such way
    Code:
    # echo "C1 DF EF E9 D8 D9 20 E0 D5 D6 D8 DC" | xxd -r -p | iconv -f ISO-8859-5 -t UTF8
    # Спящий режим
    Unfortunately naively You cant do that in Zabbix pre-processing.

    System and Network administrator

    Comment

    • Balbes
      Junior Member
      • Feb 2020
      • 7

      #3
      Да. Именно так! Правильно поставленный вопрос помог найти решение, на этом же, но англоязычном форуме нашел Java скрипт в предобработку:
      Code:
      var out = "";
      for (var i = 0, nums = value.split(" "); i < nums.length; i++) {
          out += String.fromCharCode(parseInt(nums[i], 16));
      }
      return out;
      Но тут возник очередной подводный камень. Вывод получается в кодировке ISO-8859-1, которая не имеет кириллицы. Вот пример вывода: ÁßïéØÙ àÕÖØÜ
      Как теперь сменить кодировку, на кодировку с кириллицей? Например ISO-8859-5.
      Last edited by Balbes; 18-02-2020, 09:55.

      Comment

      • Victor Sklyarov
        Senior Member
        • Apr 2016
        • 184

        #4
        Вот так:
        function snmphexdecode(hex) {
        var preStr = '';
        var preStrAr = hex.split(" ");
        for (var j = 0; j < preStrAr.length; j++) {
        preStr += String.fromCharCode(parseInt(preStrAr[j], 16));
        }
        var result = "";
        var i = 0;
        var c = c1 = c2 = 0;
        while (i < preStr.length) {
        c = preStr.charCodeAt(i);
        if (c < 128) {
        result += String.fromCharCode(c);
        i++;
        } else if ((c > 191) && (c < 224)) {
        c2 = preStr.charCodeAt(i + 1);
        result += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
        i += 2;
        } else {
        c2 = preStr.charCodeAt(i + 1);
        c3 = preStr.charCodeAt(i + 2);
        result += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
        i += 3;
        }

        }
        return result;
        }

        Comment

        • Balbes
          Junior Member
          • Feb 2020
          • 7

          #5
          Однако что-то пошло не так. При тестировании выдает ошибку: "undefined return value"

          Comment

          • Victor Sklyarov
            Senior Member
            • Apr 2016
            • 184

            #6
            Надеюсь, вы вы удалили " function snmphexdecode(hex)"?

            Вот образец : D0 9C D0 BE D0 B4 D1 83 D0 BB D1 8C 20 D1 81 D0 B1 D0 BE D1 80 D0 B0 20 D1 82 D0 BE D0 BD D0 B5 D1 80 D0 B0 20 48 50 20 43 45 32 35 34 41 00
            Вот результат преобразования: Модуль сбора тонера HP CE254A
            Можете протестировать на любом бесплатном сайте для отладки JavaScript

            Вот шаг предобработки: JavaScript
            Вот сама предобработка:
            var preStr = ''; var preStrAr = value.split(" "); for (var j = 0; j < preStrAr.length; j++) { preStr += String.fromCharCode(parseInt(preStrAr[j], 16)); } var result = ""; var i = 0; var c = c1 = c2 = 0; while (i < preStr.length) { c = preStr.charCodeAt(i); if (c < 128) { result += String.fromCharCode(c); i++; } else if ((c > 191) && (c < 224)) { c2 = preStr.charCodeAt(i + 1); result += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = preStr.charCodeAt(i + 1); c3 = preStr.charCodeAt(i + 2); result += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return result;

            Comment

            • Balbes
              Junior Member
              • Feb 2020
              • 7

              #7
              На Ваших данных получается корректно, а когда преобразуются данные с моего принтера получается: _縉٠Ֆ؜
              И в заббиксе, когда вставляю в тест предобработки свой и ваш HEX - на ваших значениях нормально, на моих значениях - кракозябры.

              Вот образец с моего принтера: C1 DF EF E9 D8 D9 20 E0 D5 D6 D8 DC
              Вот результат: _縉٠Ֆ؜

              И Ваши значения:
              Вот образец : D0 9C D0 BE D0 B4 D1 83 D0 BB D1 8C 20 D1 81 D0 B1 D0 BE D1 80 D0 B0 20 D1 82 D0 BE D0 BD D0 B5 D1 80 D0 B0 20 48 50 20 43 45 32 35 34 41 00
              Вот результат преобразования:
              Модуль сбора тонера HP CE254A
              Наши принтера выдают разные данные...
              Last edited by Balbes; 28-02-2020, 10:00.

              Comment

              • Victor Sklyarov
                Senior Member
                • Apr 2016
                • 184

                #8
                Вы пытаетесь преобразовать в UTF 16 и я вам дал скрипт для этого же. А у вас исходный текст в ISO-8859-5 (каждый байт -символ)
                Статический метод String.fromCharCode() возвращает строку, созданную из указанной последовательности значений единиц кода UTF-16.
                Попробуйте String.fromCodePoint()

                Comment

                • Balbes
                  Junior Member
                  • Feb 2020
                  • 7

                  #9
                  Не знаю, правильно или нет, но заменил и получилось так:
                  Предобработка:

                  HTML Code:
                  var preStr = ''; var preStrAr = value.split(" "); for (var j = 0; j < preStrAr.length; j++) { preStr += String.fromCodePoint(parseInt(preStrAr[j], 16)); } var result = ""; var i = 0; var c = c1 = c2 = 0; while (i < preStr.length) { c = preStr.charCodeAt(i); if (c < 128) { result += String.fromCodePoint(c); i++; } else if ((c > 191) && (c < 224)) { c2 = preStr.charCodeAt(i + 1); result += String.fromCodePoint(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = preStr.charCodeAt(i + 1); c3 = preStr.charCodeAt(i + 2); result += String.fromCodePoint(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return result;
                  В результате вывод предложенного вами значения не изменился "Модуль сбора тонера HP CE254A"

                  Вывод моего значения не изменился: "_縉٠Ֆ"

                  Вывод нового состояния принтера: "B3 DE E2 DE D2 DE" (что означает "Готово") -> Вывод теста предобработки выдал:
                  RangeError: invalid args
                  at [anon] (duktape.c:39757) internal
                  at fromCodePoint () native strict preventsyield
                  at [anon] (function:1) preventsyield

                  Comment

                  Working...