blob: 5ebf20b3dc9529fd3daaa767e307e52e8d6fa5a9 [file] [log] [blame]
Nicolas Palpacuer16138de2018-07-03 14:35:18 -04001#
2# Copyright 2018 the original author or authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
mzadig7cda5ff2018-07-10 16:37:28 -040017import arrow
mzadig7cda5ff2018-07-10 16:37:28 -040018import voltha.adapters.openolt.openolt_platform as platform
mzadige4ad1d22018-07-27 15:27:22 -040019# from voltha.protos.device_pb2 import Port
20from voltha.extensions.alarms.adapter_alarms import AdapterAlarms
21from voltha.extensions.alarms.olt.olt_los_alarm import OltLosAlarm
22from voltha.extensions.alarms.onu.onu_dying_gasp_alarm import OnuDyingGaspAlarm
23from voltha.extensions.alarms.onu.onu_los_alarm import OnuLosAlarm
24from voltha.extensions.alarms.onu.onu_lopc_miss_alarm import OnuLopcMissAlarm
25from voltha.extensions.alarms.onu.onu_lopc_mic_error_alarm import OnuLopcMicErrorAlarm
26from voltha.extensions.alarms.onu.onu_lob_alarm import OnuLobAlarm
27
mzadigb486c072018-08-08 11:34:51 -040028from voltha.extensions.alarms.onu.onu_startup_alarm import OnuStartupAlarm
29from voltha.extensions.alarms.onu.onu_signal_degrade_alarm import OnuSignalDegradeAlarm
30from voltha.extensions.alarms.onu.onu_signal_fail_alarm import OnuSignalFailAlarm
31from voltha.extensions.alarms.onu.onu_window_drift_alarm import OnuWindowDriftAlarm
32from voltha.extensions.alarms.onu.onu_activation_fail_alarm import OnuActivationFailAlarm
33
mzadige4ad1d22018-07-27 15:27:22 -040034import protos.openolt_pb2 as openolt_pb2
35import voltha.protos.device_pb2 as device_pb2
Nicolas Palpacuer16138de2018-07-03 14:35:18 -040036
37
38class OpenOltAlarmMgr(object):
mzadig7cda5ff2018-07-10 16:37:28 -040039 def __init__(self, log, adapter_agent, device_id, logical_device_id):
40 """
41 20180711 - Addition of adapter_agent and device_id
42 to facilitate alarm processing and kafka posting
43 :param log:
44 :param adapter_agent:
45 :param device_id:
46 """
Nicolas Palpacuer16138de2018-07-03 14:35:18 -040047 self.log = log
mzadig7cda5ff2018-07-10 16:37:28 -040048 self.adapter_agent = adapter_agent
49 self.device_id = device_id
50 self.logical_device_id = logical_device_id
mzadigb486c072018-08-08 11:34:51 -040051 """
52 The following is added to reduce the continual posting of OLT LOS alarming
53 to Kafka. Set enable_alarm_suppress = true to enable otherwise the
54 current openolt bal will send continuous olt los alarm cleared messages
55 ONU disc raised counter is place holder for a future addition
56 """
57 self.enable_alarm_suppress = True
58 self.alarm_suppress = {"olt_los_clear": 0, "onu_disc_raised": []} # Keep count of alarms to limit.
mzadig7cda5ff2018-07-10 16:37:28 -040059 try:
60 self.alarms = AdapterAlarms(self.adapter_agent, self.device_id, self.logical_device_id)
61 except Exception as initerr:
62 self.log.exception("alarmhandler-init-error", errmsg=initerr.message)
63 raise Exception(initerr)
Nicolas Palpacuer16138de2018-07-03 14:35:18 -040064
65 def process_alarms(self, alarm_ind):
Nicolas Palpacuer16138de2018-07-03 14:35:18 -040066 try:
mzadig7cda5ff2018-07-10 16:37:28 -040067 self.log.debug('alarm-indication', alarm=alarm_ind, device_id=self.device_id)
Nicolas Palpacuer16138de2018-07-03 14:35:18 -040068 if alarm_ind.HasField('los_ind'):
69 self.los_indication(alarm_ind.los_ind)
70 elif alarm_ind.HasField('dying_gasp_ind'):
71 self.dying_gasp_indication(alarm_ind.dying_gasp_ind)
72 elif alarm_ind.HasField('onu_alarm_ind'):
73 self.onu_alarm_indication(alarm_ind.onu_alarm_ind)
74 elif alarm_ind.HasField('onu_startup_fail_ind'):
75 self.onu_startup_failure_indication(
76 alarm_ind.onu_startup_fail_ind)
77 elif alarm_ind.HasField('onu_signal_degrade_ind'):
78 self.onu_signal_degrade_indication(
79 alarm_ind.onu_signal_degrade_ind)
80 elif alarm_ind.HasField('onu_drift_of_window_ind'):
81 self.onu_drift_of_window_indication(
82 alarm_ind.onu_drift_of_window_ind)
83 elif alarm_ind.HasField('onu_loss_omci_ind'):
84 self.onu_loss_omci_indication(alarm_ind.onu_loss_omci_ind)
85 elif alarm_ind.HasField('onu_signals_fail_ind'):
86 self.onu_signals_failure_indication(
87 alarm_ind.onu_signals_fail_ind)
88 elif alarm_ind.HasField('onu_tiwi_ind'):
89 self.onu_transmission_interference_warning(
90 alarm_ind.onu_tiwi_ind)
91 elif alarm_ind.HasField('onu_activation_fail_ind'):
92 self.onu_activation_failure_indication(
93 alarm_ind.onu_activation_fail_ind)
94 elif alarm_ind.HasField('onu_processing_error_ind'):
95 self.onu_processing_error_indication(
96 alarm_ind.onu_processing_error_ind)
97 else:
mzadige4ad1d22018-07-27 15:27:22 -040098 self.log.warn('unknown alarm type', alarm=alarm_ind)
Nicolas Palpacuer16138de2018-07-03 14:35:18 -040099
100 except Exception as e:
101 self.log.error('sorting of alarm went wrong', error=e,
102 alarm=alarm_ind)
103
104 def los_indication(self, los_ind):
mzadig7cda5ff2018-07-10 16:37:28 -0400105
Nicolas Palpacuer16138de2018-07-03 14:35:18 -0400106 try:
mzadig7cda5ff2018-07-10 16:37:28 -0400107 self.log.debug('los indication received', los_ind=los_ind,
108 int_id=los_ind.intf_id, status=los_ind.status)
mzadig7cda5ff2018-07-10 16:37:28 -0400109 try:
mzadige4ad1d22018-07-27 15:27:22 -0400110 port_type_name = platform.intf_id_to_port_type_name(los_ind.intf_id)
111 if los_ind.status == 1 or los_ind.status == "on":
mzadigb486c072018-08-08 11:34:51 -0400112 # Zero out the suppression counter on OLT_LOS raise
113 self.alarm_suppress['olt_los_clear'] = 0
mzadige4ad1d22018-07-27 15:27:22 -0400114 OltLosAlarm(self.alarms, intf_id=los_ind.intf_id, port_type_name=port_type_name).raise_alarm()
mzadig7cda5ff2018-07-10 16:37:28 -0400115 else:
mzadigb486c072018-08-08 11:34:51 -0400116 """
117 Check if there has been more that one los clear following a previous los
118 """
119 if self.alarm_suppress['olt_los_clear'] == 0 and self.enable_alarm_suppress:
120 OltLosAlarm(self.alarms, intf_id=los_ind.intf_id, port_type_name=port_type_name).clear_alarm()
121 self.alarm_suppress['olt_los_clear'] += 1
122
mzadig7cda5ff2018-07-10 16:37:28 -0400123 except Exception as alarm_err:
124 self.log.error('los-indication', errmsg=alarm_err.message)
Nicolas Palpacuer16138de2018-07-03 14:35:18 -0400125 except Exception as e:
mzadig7cda5ff2018-07-10 16:37:28 -0400126 self.log.error('los-indication', errmsg=e.message)
Nicolas Palpacuer16138de2018-07-03 14:35:18 -0400127
128 def dying_gasp_indication(self, dying_gasp_ind):
mzadig7cda5ff2018-07-10 16:37:28 -0400129 try:
130 alarm_dgi = dying_gasp_ind
131 onu_id = alarm_dgi.onu_id
132 self.log.debug('openolt-alarmindication-dispatch-dying-gasp', int_id=alarm_dgi.intf_id,
133 onu_id=alarm_dgi.onu_id, status=alarm_dgi.status)
134 try:
135 """
mzadige4ad1d22018-07-27 15:27:22 -0400136 Get the specific onu device information for the onu generating the alarm.
137 Extract the id. In the future extract the serial number as well
mzadig7cda5ff2018-07-10 16:37:28 -0400138 """
mzadige4ad1d22018-07-27 15:27:22 -0400139 onu_device_id = "unresolved"
140 onu_serial_number = "unresolved"
141 onu_device = self.resolve_onu_id(onu_id, port_intf_id=alarm_dgi.intf_id)
142 if onu_device != None:
mzadig7cda5ff2018-07-10 16:37:28 -0400143 onu_device_id = onu_device.id
mzadige4ad1d22018-07-27 15:27:22 -0400144 onu_serial_number = onu_device.serial_number
145
146 if dying_gasp_ind.status == 1 or dying_gasp_ind.status == "on":
147 OnuDyingGaspAlarm(self.alarms, dying_gasp_ind.intf_id,
148 onu_device_id).raise_alarm()
mzadig7cda5ff2018-07-10 16:37:28 -0400149 else:
mzadige4ad1d22018-07-27 15:27:22 -0400150 OnuDyingGaspAlarm(self.alarms, dying_gasp_ind.intf_id,
151 onu_device_id).clear_alarm()
mzadig7cda5ff2018-07-10 16:37:28 -0400152 except Exception as alarm_err:
153 self.log.exception('dying-gasp-indication', errmsg=alarm_err.message)
154
155 except Exception as e:
156 self.log.error('dying_gasp_indication', error=e)
Nicolas Palpacuer16138de2018-07-03 14:35:18 -0400157
158 def onu_alarm_indication(self, onu_alarm_ind):
mzadige4ad1d22018-07-27 15:27:22 -0400159 """
160 LOB = Los of burst
161 LOPC = Loss of PLOAM miss channel
162
163 :param onu_alarm_ind: Alarm indication which currently contains
164 onu_id:
165 los_status:
166 lob_status:
167 lopc_miss_status:
168 lopc_mic_error_status:
169 :return:
170 """
171 self.log.info('onu-alarm-indication')
172
173 try:
174 self.log.debug('onu alarm indication received', los_status=onu_alarm_ind.los_status,
175 onu_intf_id=onu_alarm_ind.onu_id,
176 lob_status=onu_alarm_ind.lob_status,
177 lopc_miss_status=onu_alarm_ind.lopc_miss_status,
178 lopc_mic_error_status=onu_alarm_ind.lopc_mic_error_status,
179 intf_id=onu_alarm_ind.intf_id
180 )
181
182 try:
183 """
184 Get the specific onu device information for the onu generating the alarm.
185 Extract the id. In the future extract the serial number as well
186 """
187 onu_device_id = "unresolved"
188 serial_number = "unresolved"
189 onu_device = self.resolve_onu_id(onu_alarm_ind.onu_id, port_intf_id=onu_alarm_ind.intf_id)
190 if onu_device != None:
191 onu_device_id = onu_device.id
192 serial_number = onu_device.serial_number
193
194 if onu_alarm_ind.los_status == 1 or onu_alarm_ind.los_status == "on":
195 OnuLosAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).raise_alarm()
mzadige4ad1d22018-07-27 15:27:22 -0400196 elif onu_alarm_ind.los_status == 0 or onu_alarm_ind.los_status == "off":
197 OnuLosAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).clear_alarm()
198 else: # No Change
199 pass
200
201 if onu_alarm_ind.lopc_miss_status == 1 or onu_alarm_ind.lopc_miss_status == "on":
202 OnuLopcMissAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).raise_alarm()
203 elif (onu_alarm_ind.lopc_miss_status == 0 or onu_alarm_ind.lopc_miss_status == "off"):
204 OnuLopcMissAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).clear_alarm()
205 else: # No Change
206 pass
207
208 if onu_alarm_ind.lopc_mic_error_status == 1 or onu_alarm_ind.lopc_mic_error_status == "on":
209 OnuLopcMicErrorAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).raise_alarm()
210 elif onu_alarm_ind.lopc_mic_error_status == 0 or onu_alarm_ind.lopc_mic_error_status == "off":
211 OnuLopcMicErrorAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).clear_alarm()
212 else: # No Change
213 pass
214
215 if onu_alarm_ind.lob_status == 1 or onu_alarm_ind.lob_status == "on":
216 OnuLobAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).raise_alarm()
217 elif onu_alarm_ind.lob_status == 0 or onu_alarm_ind.lob_status == "off":
218 OnuLobAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).clear_alarm()
219 else: # No Change
220 pass
221 except Exception as alarm_err:
mzadigb486c072018-08-08 11:34:51 -0400222 self.log.exception('onu-alarm-indication', errmsg=alarm_err.message)
mzadige4ad1d22018-07-27 15:27:22 -0400223
224 except Exception as e:
mzadigb486c072018-08-08 11:34:51 -0400225 self.log.exception('onu-alarm-indication', errmsg=e.message)
Nicolas Palpacuer16138de2018-07-03 14:35:18 -0400226
227 def onu_startup_failure_indication(self, onu_startup_fail_ind):
mzadigb486c072018-08-08 11:34:51 -0400228 """
229 Current protobuf indicator:
230 message OnuStartupFailureIndication {
231 fixed32 intf_id = 1;
232 fixed32 onu_id = 2;
233 string status = 3;
234 }
235
236 :param onu_startup_fail_ind:
237 :return:
238 """
239 try:
240 ind = onu_startup_fail_ind
241 label = "onu-startup-failure-indication"
242 self.log.debug(label + " received", onu_startup_fail_ind=ind, int_id=ind.intf_id, onu_id=ind.onu_id, status=ind.status)
243 try:
244 if ind.status == 1 or ind.status == "on":
245 OnuStartupAlarm(self.alarms, intf_id=ind.intf_id,onu_id=ind.onu_id).raise_alarm()
246 else:
247 OnuStartupAlarm(self.alarms, intf_id=ind.intf_id, onu_id=ind.onu_id).clear_alarm()
248 except Exception as alarm_err:
249 self.log.exception(label, errmsg=alarm_err.message)
250
251 except Exception as e:
252 self.log.exception(label, errmsg=e.message)
Nicolas Palpacuer16138de2018-07-03 14:35:18 -0400253
254 def onu_signal_degrade_indication(self, onu_signal_degrade_ind):
mzadigb486c072018-08-08 11:34:51 -0400255 """
256 Current protobuf indicator:
257 OnuSignalDegradeIndication {
258 fixed32 intf_id = 1;
259 fixed32 onu_id = 2;
260 string status = 3;
261 fixed32 inverse_bit_error_rate = 4;
262 }
263 :param onu_signal_degrade_ind:
264 :return:
265 """
266 try:
267 ind = onu_signal_degrade_ind
268 label = "onu-signal-degrade-indication"
269 self.log.debug(label + ' received',
270 onu_startup_fail_ind=ind,
271 int_id=ind.intf_id,
272 onu_id=ind.onu_id,
273 inverse_bit_error_rate=ind.inverse_bit_error_rate,
274 status=ind.status)
275 try:
276 if ind.status == 1 or ind.status == "on":
277 OnuSignalDegradeAlarm(self.alarms, intf_id=ind.intf_id, onu_id=ind.onu_id,
278 inverse_bit_error_rate=ind.inverse_bit_error_rate).raise_alarm()
279 else:
280 OnuSignalDegradeAlarm(self.alarms, intf_id=ind.intf_id, onu_id=ind.onu_id,
281 inverse_bit_error_rate=ind.inverse_bit_error_rate).clear_alarm()
282 except Exception as alarm_err:
283 self.log.exception(label, errmsg=alarm_err.message)
284
285 except Exception as e:
286 self.log.exception(label, errmsg=e.message)
Nicolas Palpacuer16138de2018-07-03 14:35:18 -0400287
288 def onu_drift_of_window_indication(self, onu_drift_of_window_ind):
mzadigb486c072018-08-08 11:34:51 -0400289 """
290 Current protobuf indicator:
291 OnuDriftOfWindowIndication {
292 fixed32 intf_id = 1;
293 fixed32 onu_id = 2;
294 string status = 3;
295 fixed32 drift = 4;
296 fixed32 new_eqd = 5;
297 }
298
299 :param onu_drift_of_window_ind:
300 :return:
301 """
302 try:
303 ind = onu_drift_of_window_ind
304 label = "onu-window-drift-indication"
305
306 onu_device_id, onu_serial_number = self.resolve_onudev_id_onudev_serialnum(
307 self.resolve_onu_id(ind.onu_id, port_intf_id=ind.intf_id))
308
309 self.log.debug(label + ' received',
310 onu_drift_of_window_ind=ind,
311 int_id=ind.intf_id,
312 onu_id=ind.onu_id,
313 onu_device_id=onu_device_id,
314 drift=ind.drift,
315 new_eqd=ind.new_eqd,
316 status=ind.status)
317 try:
318 if ind.status == 1 or ind.status == "on":
319 OnuWindowDriftAlarm(self.alarms, intf_id=ind.intf_id,
320 onu_id=onu_device_id,
321 drift=ind.drift,
322 new_eqd=ind.new_eqd).raise_alarm()
323 else:
324 OnuWindowDriftAlarm(self.alarms, intf_id=ind.intf_id,
325 onu_id=onu_device_id,
326 drift=ind.drift,
327 new_eqd=ind.new_eqd).clear_alarm()
328 except Exception as alarm_err:
329 self.log.exception(label, errmsg=alarm_err.message)
330
331 except Exception as e:
332 self.log.exception(label, errmsg=e.message)
Nicolas Palpacuer16138de2018-07-03 14:35:18 -0400333
334 def onu_loss_omci_indication(self, onu_loss_omci_ind):
335 self.log.info('not implemented yet')
336
337 def onu_signals_failure_indication(self, onu_signals_fail_ind):
mzadigb486c072018-08-08 11:34:51 -0400338 """
339 Current protobuf indicator:
340 OnuSignalsFailureIndication {
341 fixed32 intf_id = 1;
342 fixed32 onu_id = 2;
343 string status = 3;
344 fixed32 inverse_bit_error_rate = 4;
345 }
346
347 :param onu_signals_fail_ind:
348 :return:
349 """
350 try:
351 ind = onu_signals_fail_ind
352 label = "onu-signal-failure-indication"
353
354 onu_device_id, onu_serial_number = self.resolve_onudev_id_onudev_serialnum(
355 self.resolve_onu_id(ind.onu_id, port_intf_id=ind.intf_id))
356
357 self.log.debug(label + ' received',
358 onu_startup_fail_ind=ind,
359 int_id=ind.intf_id,
360 onu_id=ind.onu_id,
361 onu_device_id=onu_device_id,
362 onu_serial_number=onu_serial_number,
363 inverse_bit_error_rate=ind.inverse_bit_error_rate,
364 status=ind.status)
365 try:
366 if ind.status == 1 or ind.status == "on":
367 OnuSignalFailAlarm(self.alarms, intf_id=ind.intf_id,
368 onu_id=onu_device_id,
369 inverse_bit_error_rate=ind.inverse_bit_error_rate).raise_alarm()
370 else:
371 OnuSignalFailAlarm(self.alarms, intf_id=ind.intf_id,
372 onu_id=onu_device_id,
373 inverse_bit_error_rate=ind.inverse_bit_error_rate).clear_alarm()
374 except Exception as alarm_err:
375 self.log.exception(label, errmsg=alarm_err.message)
376
377 except Exception as e:
378 self.log.exception(label, errmsg=e.message)
379
Nicolas Palpacuer16138de2018-07-03 14:35:18 -0400380
381 def onu_transmission_interference_warning(self, onu_tiwi_ind):
382 self.log.info('not implemented yet')
383
384 def onu_activation_failure_indication(self, onu_activation_fail_ind):
mzadigb486c072018-08-08 11:34:51 -0400385 """
386
387 No status is currently passed with this alarm. Consequently it will always just raise
388 :param onu_activation_fail_ind:
389 :return:
390 """
391 try:
392 ind = onu_activation_fail_ind
393 label = "onu-activation-failure-indication"
394
395 onu_device_id, onu_serial_number = self.resolve_onudev_id_onudev_serialnum(
396 self.resolve_onu_id(ind.onu_id, port_intf_id=ind.intf_id))
397
398 self.log.debug(label + ' received',
399 onu_startup_fail_ind=ind,
400 int_id=ind.intf_id,
401 onu_id=ind.onu_id,
402 onu_device_id=onu_device_id,
403 onu_serial_number=onu_serial_number)
404 try:
405
406 OnuActivationFailAlarm(self.alarms, intf_id=ind.intf_id,
407 onu_id=onu_device_id).raise_alarm()
408 except Exception as alarm_err:
409 self.log.exception(label, errmsg=alarm_err.message)
410
411 except Exception as e:
412 self.log.exception(label, errmsg=e.message)
Nicolas Palpacuer16138de2018-07-03 14:35:18 -0400413
414 def onu_processing_error_indication(self, onu_processing_error_ind):
mzadig7cda5ff2018-07-10 16:37:28 -0400415 self.log.info('not implemented yet')
mzadige4ad1d22018-07-27 15:27:22 -0400416
mzadigb486c072018-08-08 11:34:51 -0400417 """
418 Helper Methods
419 """
420
421 def resolve_onudev_id_onudev_serialnum(self,onu_device):
422 """
423 Convenience wrapper to resolve device_id and serial number
424 :param onu_device:
425 :return: tuple: onu_device_id, onu_serial_number
426 """
427 try:
428 onu_device_id = "unresolved"
429 onu_serial_number = "unresolved"
430 if onu_device != None:
431 onu_device_id = onu_device.id
432 onu_serial_number = onu_device.serial_number
433 except Exception as err:
434 self.log.exception("openolt-alarms-resolve-onudev-id ", errmsg=err.message)
435 raise Exception(err)
436 return onu_device_id, onu_serial_number
437
mzadige4ad1d22018-07-27 15:27:22 -0400438 def resolve_onu_id(self, onu_id, port_intf_id):
439 """
440 Resolve the onu_device from the intf_id value and port. Uses the adapter agent to
441 resolve this..
442
443 Returns None if not found. Caller will have to test for None and act accordingly.
444 :param onu_id:
445 :param port_intf_id:
446 :return:
447 """
448
449 try:
450 onu_device = None
451 onu_device = self.adapter_agent.get_child_device(
452 self.device_id,
453 parent_port_no=platform.intf_id_to_port_no(
454 port_intf_id, device_pb2.Port.PON_OLT),
455 onu_id=onu_id)
456 onu_device_id = onu_device.id
457 except Exception as inner:
458 self.log.exception('resolve-onu-id', errmsg=inner.message)
459
460 return onu_device
461