Changes between Initial Version and Version 1 of MonitoringSFP


Ignore:
Timestamp:
Jun 6, 2025, 4:01:06 PM (41 hours ago)
Author:
alx
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • MonitoringSFP

    v1 v1  
     1= Мониторинг параметров SFP на примере температуры и уровня принимаемого сигнала =
     2
     3В данной статье рассматривается пример мониторинга параметров модуля SFP, установленного в плату SW-01 блока MC04-DSL-3U, с помощью системы мониторинга Zabbix и встроенного в плату SW-01 агента Zabbix. Предполагается, что у нас уже имеется настроенный и работающий сервер Zabbix, в котором настроен мониторинг блока MC04-DSL-3U, а в плате SW-01 блока настроена работа агента Zabbix с сервером Zabbix.
     4
     5Настройка сервера Zabbix описана в [https://www.zabbix.com/documentation/current/en руководстве Zabbix], настройка агента Zabbix в плате SW-01 описана в [https://adc-line.ru/pdf/mc04-dsl-3u-re.pdf руководстве по эксплуатации MC04-DSL-3U].
     6
     7== Получение блока параметров SFP ==
     8
     9Модули SFP содержат в себе идентификационную информацию, которая может быть прочитана из него устройством-хостом с адреса 0xA0 и отображена пользователю или использована каким-то иным образом. Некоторые модули SFP в дополнение к идентификационным данным имеют возможность предоставлять данные измерений и диагностики, содержащие различные параметры, измеряемые в процессе работы модуля, а также индикацию аварийных состояний, которая может быть прочитана из него устройством-хостом с адреса 0xA2.
     10
     11Данные модуля SFP, установленного в плату SW-01, могут быть получены сервером Zabbix посредством функции `readsfp` агента Zabbix (см. [ZabbixAgent#Ключиэлементовданных ZabbixAgent]). Прочитанные из SFP данные возвращаются в форме массива Json. Каждый элемент массива содержит значение одного байта (0-255), прочитанного из SFP. В случае, если SFP поддерживает как идентификацию, так и измерение/диагностику, возвращаемый массив имеет размер 512. Первые 256 байт массива представляют собой идентификационную информацию, следующие 256 байт - данные измерений/диагностики. Если SFP не имеет функции измерения/диагностики, массив будет содержать только 256 байт данных идентификации. Формат данных описан в стандарте SFF-8472, его можно прочитать, например, [https://members.snia.org/document/dl/25916 здесь].
     12
     13Для начала нам необходимо получать данные из SFP и сохранять их в базе данных сервера. Для этого создадим элемент данных `SFP data (slot 9)`, указав ключ `MC04.SW-01.readsfp[9]`:
     14
     15[[Image(ss2.jpg)]]
     16
     17Элемент данных `SFP data (slot 10)` для SFP платы SW-01 в слоте 10 создается аналогично, только вместо слота 9 указывается слот 10 и ключ `MC04.SW-01.readsfp[10]`.
     18
     19Через 10-15 минут (необходимых для обновления списка параметров агентами плат SW-01) после создания элементов убедимся, что сервер получает данные, для чего найдем созданные нами параметры в разделе "Последние данные":
     20
     21[[Image(ss1.jpg)]]
     22
     23Если данных нет, убедитесь, что в плату SW-01 установлен SFP, и что SFP поддерживает диагностику (в веб-интерфейсе платы SW-01 при нажатии кнопки "SFP" должна отображаться информация, включающая температуру и мощность принимаемого сигнала).
     24
     25== Извлечение параметров из данных диагностики SFP ==
     26
     27Для извлечения отдельных параметров из общего массива данных диагностики модуля SFP мы воспользуется элементами данных Zabbix типа "Зависимый элемент данных". Зависимые элементы перевычисляются каждый раз, когда сервер получает новое значение основного элемента данных.
     28
     29=== Извлечение значения температуры из данных SFP ===
     30
     31Для извлечения значения температуры создадим зависимый элемент данных:
     32
     33[[Image(ss3.jpg)]]
     34
     35Собственно извлечение значения температуры из массива данных будем производить скриптом javascript. Для этого на вкладке "Предобработка" добавим элемент типа JavaScript. В поле "Параметры" этого элемента запишем такой скрипт:
     36
     37{{{#!javascript
     38var v = eval(value);
     39if(v.length < 512) throw 'No diagnostic data';
     40var x = v[352] * 256 + v[353];
     41if(x & 0x8000) x -= 65536;
     42if(v[92] & 0x10) {
     43  var Ts = v[340] + v[341] / 256;
     44  var To = v[342] * 256 + v[343];
     45  if(To & 0x8000) To -= 65536;
     46  x = x * Ts + To;
     47}
     48return x / 256;
     49}}}
     50
     51Разберем этот скрипт подробнее.
     52
     53{{{#!javascript
     54var v = eval(value);
     55}}}
     56
     57Первая строчка скрипта преобразует текстовую строку `value`, которую мы получили от агента из платы SW-01, в массив `v`.
     58
     59{{{#!javascript
     60if(v.length < 512) throw 'No diagnostic data';
     61}}}
     62
     63Следующая строчка проверяет, содержатся ли в полученном массиве данные диагностики. Если данных диагностики нет (размер массива меньше 512), скрипт выбрасывает исключение. Значением исключения является сообщение об ошибке, которое можно бeдет увидеть в веб-интерфейсе сервера Zabbix.
     64
     65{{{#!javascript
     66var x = v[352] * 256 + v[353];
     67if(x & 0x8000) x -= 65536;
     68}}}
     69
     70В первой строчке этого фрагмента из данных диагностики извлекается 16-битное "сырое" значение температуры. Это значение в данных диагностики занимает 2 байта начиная со смещения 96, что с учетом данных идентификации модуля дает нам смещение (256 + 96) = 352. Старший бит "сырого" значения является знаком, поэтому вторая строчка фрагмента преобразует значение в отрицательное если старший бит равен единице.
     71
     72{{{#!javascript
     73if(v[92] & 0x10) {
     74  var Ts = v[340] + v[341] / 256;
     75  var To = v[342] * 256 + v[343];
     76  if(To & 0x8000) To -= 65536;
     77  x = x * Ts + To;
     78}
     79}}}
     80
     81Измеренные значения, выдаваемые модулем SFP, могут быть внутренне калибруемыми или внешне калибруемыми. Внутренне калибруемые значения уже откалиброваны самим модулем и представляют измеренную физическую величину (в данном случае температуру) в определенном масштабе (в случае температуры - в 1/256 градуса). Внешне калибруемые значения представляют собой данные АЦП, которые для получения значения физического параметра требуется дополнительно откалибровать по несложной формуле с использованием нескольких коэффициентов. О том, какая калибровка данных ипльзуется модулем, говорят флаги в байте 92 идентификационных данных SFP. Первая строчка данного фрагмента кода проверяет, требуется ли выполнять внешнюю калибровку. Если бит 4 в байте 92 установлен в значение 1, значит требуется выполнить внешнюю калибровку.
     82
     83Калибровка температуры выполняется по формуле:
     84
     85{{{#!plantuml
     86@startuml
     87:<math>T = T_(AD) * T_s + T_o</math>;
     88@enduml
     89}}}
     90
     91где T,,AD,, - "сырое" значение температуры, считанное с АЦП (оно у нас уже содержится в переменной `x`), T,,s,, и T,,o,, - 16-битные коэффициенты, хранящиеся в данных диагностики по смещениям 84 и 86 соответственно, что дает нам смещения в массиве `v` (256 + 84) = 340 и (256 + 86) = 342 соответственно. Коэффициент T,,s,, - беззнаковый с фиксированной точкой, имеет масштаб 1/256. Коэффициент T,,o,, имеет знаковый формат, поэтому дополнительным условием проверяется знак и выполняется преобразование к отрицательному значению.
     92
     93{{{#!javascript
     94return x / 256;
     95}}}
     96
     97Последняя строчка скрипта возвращает результат вычислений в градусах Цельсия. Так как, как уже было сказано выше, значение температуры возвращается модулем в единицах 1/256 градуса, итоговое значение делится на 256.
     98
     99В заключение отмечу, что стандарт SFF-8472 требует, чтобы при внутренней калибровке значений калибровочные коэффициенты T,,s,, и T,,o,, имели значения 1 и 0 соответственно и, таким образом, формула калибровки
     100
     101{{{#!plantuml
     102@startuml
     103:<math>T = T_(AD) * T_s + T_o</math>;
     104@enduml
     105}}}
     106
     107превращается в формулу
     108
     109{{{#!plantuml
     110@startuml
     111:<math>T = T_(AD)</math>;
     112@enduml
     113}}}
     114
     115Благодаря этому мы можем упростить скрипт, убрав из него проверку флага внешней калибровки в байте 92:
     116
     117{{{#!javascript
     118var v = eval(value);
     119if(v.length < 512) throw 'No diagnostic data';
     120var x = v[352] * 256 + v[353];
     121if(x & 0x8000) x -= 65536;
     122var Ts = v[340] + v[341] / 256;
     123var To = v[342] * 256 + v[343];
     124if(To & 0x8000) To -= 65536;
     125x = x * Ts + To;
     126return x / 256;
     127}}}
     128
     129Аналогично создается элемент данных для мониторинга температуры SFP платы SW-01 в слоте 10.
     130
     131После создания элемента убедимся, что в разделе "последние данные" начало отображаться значение температуры модуля SFP:
     132
     133[[Image(ss4.jpg)]]
     134
     135=== Извлечение значения уровня принимаемого сигнала из данных SFP ===
     136
     137Для извлечения значения уровня принимаемого сигнала создадим зависимый элемент данных:
     138
     139[[Image(ss5.jpg)]]
     140
     141Извлечение данных производится аналогично параметру температуры. Элемент предобратотки содержит такой скрипт:
     142
     143{{{#!javascript
     144var v = eval(value);
     145if(v.length < 512) throw 'No diagnostic data';
     146var buffer = new ArrayBuffer(20);
     147var view = new DataView(buffer);
     148for(var i = 0, j = 312; i < 20; i++, j++)
     149    view.setUint8(i, v[j]);
     150var rxpwr = v[360] * 256 + v[361];
     151rxpwr = Math.pow(rxpwr,4) * view.getFloat32(0, false) +
     152        Math.pow(rxpwr,3) * view.getFloat32(4, false) +
     153        Math.pow(rxpwr,2) * view.getFloat32(8, false) +
     154        rxpwr * view.getFloat32(12, false) +
     155        view.getFloat32(16, false);
     156return rxpwr / 10000;
     157}}}
     158
     159Давайте разберем некоторые фрагменты этого скрипта подробнее.
     160
     161{{{#!javascript
     162var buffer = new ArrayBuffer(20);
     163var view = new DataView(buffer);
     164}}}
     165
     166Согласно стандарту SFF-8472, внешняя калибровка значения принимаемой мощности выполняется по следующей формуле:
     167
     168{{{#!plantuml
     169@startuml
     170:<math>Rx_(PWR) = P_(AD)^4 * K_4 + P_(AD)^3 * K_3 + P_(AD)^2 * K_2 + P_(AD) * K_1 + K_0</math>;
     171@enduml
     172}}}
     173
     174где P,,AD,, - "сырое" значение принимаемой мощности, K,,0,, - K,,4,, - коэффициенты калибровки. Коэффициенты K,,0,, - K,,4,, представляют собой 32-битные числа с плавающей точкой - таким образом, пять коэффициентов занимают (5 * 4) = 20 байт. Значения коэффициентов хранятся в данных диагностики начиная со смещения 56 или, с учетом данных идентификации, (256 + 56) = 312. Для преобразования байтовых значений в числа с плавающей точкой создается ArrayBuffer размером 20 байт и интерфейс DataView для записи в буфер и чтения из буфера значений.
     175
     176{{{#!javascript
     177for(var i = 0, j = 312; i < 20; i++, j++)
     178    view.setUint8(i, v[j]);
     179}}}
     180
     181В этом фрагменте скрипта 20 байт, представляющих значения коэффициентов, загружаются в созданный нами буфер.
     182
     183{{{#!javascript
     184var rxpwr = v[360] * 256 + v[361];
     185}}}
     186
     18716-битное значение принимаемой мощности читается из данных диагностики по смещению 104 (с учетом данных идентификации - 360).
     188
     189{{{#!javascript
     190rxpwr = Math.pow(rxpwr,4) * view.getFloat32(0, false) +
     191        Math.pow(rxpwr,3) * view.getFloat32(4, false) +
     192        Math.pow(rxpwr,2) * view.getFloat32(8, false) +
     193        rxpwr * view.getFloat32(12, false) +
     194        view.getFloat32(16, false);
     195}}}
     196
     197В этом фрагменте выполняется внешняя калибровка по приведенной выше формуле. Как и в случае параметра температуры, стандарт требует, чтобы в случае внутренней калибровки коэффициент K,,1,, был равен единице, а все остальные коэффициенты - нулю. Благодаря этому нет необходимости в проверке, какой тип калибровки применяется в конкретном SFP.
     198
     199{{{#!javascript
     200return rxpwr / 10000;
     201}}}
     202
     203Значение принимаемой мощности, читаемое из SFP, выражено в единицах 0.1 мкВт. В приведенной строке скрипта значение делится на 10000 для получения значения в милливаттах.
     204
     205Аналогично создается элемент данных для мониторинга принимаемой мощности SFP платы SW-01 в слоте 10.
     206
     207После создания элементов убедимся, что в разделе "последние данные" начали отображаться значения принимаемой мощности.